Reputation: 565
I am new to laravel and making authentication system where a user can login using facebook,twitter or simple by email
i have made two tables
1-user
2-user_social_accounts
There is one-to-many relationship between them(a user can have many social accounts).
Model details are
User model
public function user_social_accounts()
{
return $this->hasMany('App\UserSocialAccount');
}
UserSocialAccount model
public function user()
{
return $this->belongsTo('App\User');
}
now here is logic
Case1-
-if user first signup using email then a new record will be created
-If user login using facebook then his email will store into user
table and facebook data will be store in user_social_accounts
table
-if user again login using the same email with twitter then a new record will be created in user_social_accounts
Case2-
-If user first login using social site and his record does not exist with that email, then at first his email will be stored in user
table and then facebook data will be stored in user_social_accounts
table
-if user then again signup using same email (simple login) then i would update that email record in databse(if exist).
So it is like if does not exist then create and if exist then update(based on email).
I am very close but stuck from last 1 day
Here is my Auth controller
public function facebook_login(Request $request) {
$validator = Validator::make($request->all(), [
'first_name' => 'required',
'last_name' => 'required',
'photo' => 'required',
'email' => 'required|email',
'facebook_id' => 'required',
'fcm_token' => 'required'
]);
if($validator->fails()){
$status = 0;
$data['message'] = $validator->errors();
return response()->json(['status' => $status,'data' => $data], 401);
}
$input = $request->all();
$user = User::updateOrCreate(['email' => $input['email']],$input);
$user = User::find($user['id']);
$account_details = new UserSocialAccount();
$account_details->first_name = $input['first_name'];
$account_details->last_name = $input['last_name'];
$account_details->photo = $input['photo'];
$account_details->provider_id = $input['facebook_id'];
$account_details->provider_name = 'facebook';
$account_details->fcm_token = $input['fcm_token'];
$input['provider_name'] = 'facebook';
//the following line is saving new records and not updating them
$user->user_social_accounts()->save($account_details);
}
the following line is saving new records and not updating them
$user->user_social_accounts()->save($account_details);
Please guide me I am worried.Thanks and advance sorry for any silly question.
Upvotes: 1
Views: 373
Reputation: 5149
You are currently creating a new record and then saving it, so this is the expected behavior. You will need to approach this differently. In my opinion, the relationship just gets in the way in this case.
Instead, I would do it like this and refer to the relationship manually:
// ... previous code
$input = $request->all();
$user = User::updateOrCreate([
'email' => $input['email']
],$input);
$account_details = UserSocialAccount::updateOrCreate([
'user_id' => $user->id, // refer to the relationship manually
'provider_name' => 'facebook'
],[
'first_name' => $input['first_name'],
'last_name' => $input['last_name'],
'photo' => $input['photo'],
'provider_id' => $input['facebook_id'],
'fcm_token' => $input['fcm_token'],
])
// then if you need the new relationship loaded in your response
$user->load('user_social_accounts');
// do more stuff...
EDIT : As a post script, I will add that any time you are performing multiple related database inserts like this, you should really consider using transactions. You can find more information at the link below.
https://laravel.com/docs/5.8/database#database-transactions
I hope this helps and good luck!
Upvotes: 1