Reputation: 3159
In my RegistrationController@store, I am doing the following:
hasMany()
Points, hasOne()
Profile, belongsToMany()
Role)belongsToMany()
User)belongsTo()
User)belongsTo()
User)I realized if one of these steps fails, for example if due to slow connectivity the profile is somehow not created, my app will break. Here is my store method:
public function store(){
$profile = new Profile();
$points = new Points();
$this->validate(request(),[
'name' => 'required',
'username' => 'required|unique:users',
'email' => 'required|email|unique:users',
'password' => 'required|confirmed',
'role_id' => 'required|between:1,2'
]);
$user = User::create([
'name' => request('name'),
'username' => request('username'),
'email' => request('email'),
'password' => bcrypt(request('password'))
]);
$role_student = Role::where('title', 'Student')->first();
$role_parent = Role::where('title', 'Parent')->first();
if(request()->input('role_id') == 1){
$user->roles()->attach($role_student);
} else if(request()->input('role_id') == 2){
$user->roles()->attach($role_parent);
}
$profile->user_id = $user->id;
$profile->date_of_birth = Carbon::createFromDate(request('year'),request('month'),request('day'));
$profile->institution = request('institution');
$profile->class = request('class');
$profile->division = request('division');
$profile->photo = 'propic/default.png';
$profile->bio = 'I am a Member!';
$profile->social_link = 'http://facebook.com/zuck';
$profile->save();
auth()->login($user);
\Mail::to($user)->send(new Welcome($user));
$points->updateOrCreateAndIncrement(0);
return redirect()->home();
}
It is worth mentioning that, all of the data is coming from a registration form. How can I execute all these steps at a time (or, in one statement) so that if the statement executes successfully, I will have a perfectly synchronized registration, otherwise, no data will be persisted to the database?
Upvotes: 0
Views: 386
Reputation: 739
Use transactions.
Before the first DB operation, in your case: User::create, use this:
DB::beginTransaction();
From now on, put all of your db operations in try/catch braces and if any exception happens, use:
DB::rollBack();
And at the end of the function, before return statement, put this:
DB::commit();
If you can have all your operations in the same place, it's easier to do this:
DB::transaction(function () {
//all your db opertaions
}, 2);
Upvotes: 1