Saving one to one relation in Laravel
Solution 1
Creating and updating need to treat differently. So check the existence of company attribute first.
$user = User::with('company')->findOrFail(1);
if ($user->company === null)
{
$company = new Company(['name' => 'Test']);
$user->company()->save($company);
}
else
{
$user->company->update(['name' => 'Test']);
}
Note that hasOne()
does not guarantee that you will have one-to-one relationship, it just telling Eloquent how to create query. It works even you have multiple Company
refer to same User
, in such case when you call $user->company
you will get first Company
in the result data set from database.
Solution 2
$user = User::findOrFail(1);
$company = $user->company ?: new Company;
$company->name = 'Test';
$user->company()->save($company);
Solution 3
I'm trying to save (so create or update) a user's company
You can do exactly that with the updateOrCreate method:
User::findOrFail(1)->company()->updateOrCreate([],['name' => 'xyz']);
The first parameter of updateOrCreate
is an empty array, because the companies id
is determined by the hasOne
relationship $user->company()
.
And by the way, I would recommend not using an auto-increment id field in a hasOne
relationship. If you set user_id
as primary in your company table, its technically not possible to create duplicate company rows for one user. Check out my blog post for more.
rap-2-h
Laravel enthusiast & Rust artisan. Resume: https://raph.site/en
Updated on July 19, 2022Comments
-
rap-2-h almost 2 years
A
User
has one (or zero)Company
, and aCompany
belongs to one and only oneUser
. I try to save a company for a user but it adds a new entry in database every time I re-trigger the save method. It's a one to one relation, so I thoughsave
method onUser
.So
Company
has one methoduser()
:public function user() { return $this->belongsTo(User::class, 'user_id'); }
And
User
has one methodcompany()
:public function company() { return $this->hasOne(Company::class, 'user_id'); }
I'm trying to save (so create or update) a user's company like this (in a Controller):
$company = new Company(); $company->name = 'Test'; User::findOrFail(1)->company()->save($company);
First time I run this code it creates the entry in database (OK), but second time it adds a new entry for the same user (Not OK). I thought it will only update the database entry.
Is it a glitch (or something I don't understand in one to one relation) in Laravel or am I doing something wrong? (I think and hope it's the second purpose)