Laravel saving data to two locations - php

I'm working on a larvel project where the user can create appointments. In addition I've created another model called clients so when a user creates an appointment the users "client" data is saved.
In my appointments controller I have the following: -
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
]);
//create appointment
$apt = new Appointment;
$apt->name = $request->input('name');
$apt->user_id = auth()->user()->id;
$apt->save();
//create client
$client = new Client;
$client->first_name = $request->input('name');
$client->user_id = auth()->user()->id;
$client->save();
return redirect('/appointments')->with('success', 'Appointment created');
}
When saving the data it works and stores the data in the clients table however I know this isn't the cleanest way of saving the data, but what is the "laravel" way of doing this?

There's nothing wrong with your code. It's totally fine keeping it that way.
I prefer to say Model::create() to create models in one statement.
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
]);
Appointment::create([
'name' => request('name'),
'user_id' => auth()->id()
]);
Client::create([
'first_name' => request('name'),
'user_id' => auth()->id,
]);
return redirect('/appointments')->with('success', 'Appointment created');
}
You can also use tap() function:
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
]);
tap(Appointment::create(['name' => request('name'), 'user_id' => auth()->id()]), function ($newAppoinment) {
Client::create([
'first_name' => $newAppoinment->name,
'user_id' => auth()->id,
]);
});
return redirect('/appointments')->with('success', 'Appointment created');
}
Or the best approach could be using model events:
class Appointment extends Model
{
public static function boot()
{
parent::boot();
static::created(function ($appointment) {
Client::create([
'user_id' => $appoinment->user_id,
'first_name' => $appoinment->name,
])
});
}
}

Related

Laravel Update Function Don't Save New Data

So I have trouble updating data from edit form. I tried to use 'dd' and it's collect all the data it needs. No error, but the data on database not change.
public function update(Request $request, Stationery $stationery)
{
$validated = $request->validate([
'category_id' => 'required',
'nama' => 'required',
'satuan' => 'nullable',
'harga' => 'required',
'keterangan' => 'nullable'
]);
// dd($validated);
Stationery::where('id', $stationery->id)
->update($validated);
return redirect('/barang/pakaihabis')->with('success', 'Data Berhasil Diubah!!');
}
The success message pop out but the data still same.
The only protected in the model Stationery
protected $guarded = ['id'];
You can use:
$stationery->update($validated);
There is no need for where because you use route model binding ;)

Why would the update produce this result ` {"email":"try#gmail.com"}` in the database

when i try to update email column for the user i get a weird input in the database and i don't see why. The output in the email column in the database looks something like this {"email":"try#gmail.com"} instead of just the email
HomeController
protected function createMail(Request $request)
{
$data = request()->validate([
'email' => 'required',
]);
$id = Auth::guard('web')->id();
User::where('id', $id)->update(['email' => $data]);
}
$data in your case is defined as a result of ->validate() function, but you need the value of email.
Value can be accessed with $request->get('email').
so your function should look like this:
protected function createMail(Request $request)
{
$this->validate($request, [
'email' => 'required',
]);
$id = Auth::guard('web')->id();
User::where('id', $id)->update(['email' => $request->get('email')]);
}
you are updating wrong value and it should be like this
protected function createMail(Request $request)
{
$this->validate($request, [
'email' => 'required',
]);
$id = Auth::guard('web')->id();
User::where('id', $id)->update(['email' => $request->get('email')]);
}
as you see request->get('email') instead of ['email' => $data]

How to get id When Using Implicit Route Model Binding, i need it in unique validation

// in the validation section "alias" field should be unique so i need this NursingHome object id(primary key) to force validation to not to check for this id.
I have checked it with $nursinghome->getKey() method but no success.
public function update(Request $request, NursingHome $nursinghome)
{
$request->validate([
'name' => 'required|string|max:255',
'address' => 'nullable|string',
'alias' => 'required|string|unique:nursing_home,'.$nursinghome->id,
]);
$data = $request->all();
$data['updated_by'] = Auth::guard('api')->id();
$nursinghome->update($data);
return response()->json($nursinghome, 200);
}
There is a know issue disscussed in laravel github, that if your model has two words like NursingHome the it is not injected in controller:
public function update(Request $request, $id){
$nursinghome = NursingHome::find($id); //now you will get $nursinghome->id
$request->validate([
'name' => 'required|string|max:255',
'address' => 'nullable|string',
'alias' => 'required|string|unique:nursing_home,'.$nursinghome->id,
]);
$data = $request->all();
$data['updated_by'] = Auth::guard('api')->id();
$nursinghome->update($data);
return response()->json($nursinghome, 200);
}
If your model having two or more words, you have to use only small letters.

how to make same function for create and update in laravel controller file for create and update operation?

I already have same form for both.
my controller below shows two separate function for create and update
i am new to Laravel framework, and i am working on Address book project.
for creating new:
public function store(Request $request) // for creating new member
{
request()->validate([
'name' => 'required',
'email' => 'required',
'address'=>'required',
'phone'=>'required',
]);
Member::create($request->all());
return redirect()->route('members.index')
->with('success','Member created successfully');
}
public function update(Request $request,Member $member) //for updating member info
{
request()->validate([
'name' => 'required',
'email' => 'required',
'address'=>'required',
'phone'=>'required',
]);
$member->update($request->all());
return redirect()->route('members.index')
->with('success','Member updated successfully');
}
I need to make only one function for both of the operations.thank you in advance.
Define your route
Route::post('createanddelete/{id?}','YourController#yourFunction');
By giving ? in route means that optional parameters
In your controller
public function yourFunction($id = null, Request $request)
{
request()->validate([
'name' => 'required',
'email' => 'required',
'address'=>'required',
'phone'=>'required',
]);
// write update code
if($id)
{
$member = Member::find($id);
if($member)
{
$member->update($request->all());
return redirect()->route('members.index')
->with('success','Member updated successfully');
}
}
// write create code
else
{
Member::create($request->all());
return redirect()->route('members.index')
->with('success','Member created successfully');
}
}
In the view provider the action of form accordingly.
Hope this will help, but you should write separate function for modular code

Retry logic on model save - Laravel

User_code is generated and must be unique. What would be the easiest/cleanest way to do retry logic on this model save? I would like to verify the generated code first, and then if it's not found on the users table, create the user, if found, loop to retry. What would be the syntax for that? Thanks
public function create(array $data)
{
$user = User::create([
'user_name' => 'My user name',
'user_code' => bin2hex(openssl_random_pseudo_bytes(16))
]);
$user->save();
return $user;
}
Why don't you check the database when generating the code? That way, you only try to create once you got it right and the end user doesn't have to face an error that is not up to him/her.
do {
$code = bin2hex(openssl_random_pseudo_bytes(16));
$record = User::where('user_code', $code)->get();
} while(!empty($record));
$user = User::create([
'user_name' => 'My user name',
'user_code' => $code
]);
return $user;
You could avoid the retry:
public function create(Request $request)
{
$request->merge(['user_code' => bin2hex(openssl_random_pseudo_bytes(16))]);
$this->validate($request, [
'user_name' => 'required|unique:users',
'user_code' => 'required|unique:users',
]);
$user = new User;
$user->user_name = $request->user_name;
$user->user_code = $request->user_code;
$user->save();
return $user;
}
You should create a unique string from the beginning. Still go for validation, of course.
public function create(Request $request)
{
$user_code = bcrypt($request->user_name . openssl_random_pseudo_bytes(16));
$request->merge(['user_code' => $user_code]);
$this->validate($request, [
'user_name' => 'required|unique:users',
'user_code' => 'required|unique:users',
]);
$user = User::create($request);
return $user;
}
A save() is implied by create().

Categories