在 Laravel 中保存一对一的关系
Posted
技术标签:
【中文标题】在 Laravel 中保存一对一的关系【英文标题】:Saving one to one relation in Laravel 【发布时间】:2015-12-06 12:28:52 【问题描述】:User
有一个(或零)Company
,Company
属于一个且仅一个 User
。我尝试为用户保存公司,但每次我重新触发保存方法时,它都会在数据库中添加一个新条目。这是一对一的关系,所以我在User
上使用了save
方法。
所以Company
有一种方法user()
:
public function user()
return $this->belongsTo(User::class, 'user_id');
而User
有一种方法company()
:
public function company()
return $this->hasOne(Company::class, 'user_id');
我正在尝试像这样(在控制器中)保存(因此创建或更新)用户的公司:
$company = new Company();
$company->name = 'Test';
User::findOrFail(1)->company()->save($company);
我第一次运行此代码时,它会在数据库中创建条目(OK),但第二次它会为同一用户添加一个新条目(Not OK)。我以为它只会更新数据库条目。
这是 Laravel 中的一个小故障(或者我在一对一关系中不理解的问题)还是 我做错了什么?(我认为并希望这是第二个目的)
【问题讨论】:
检查这个答案,它可能会帮助你:***.com/a/20764237/5122070 谢谢,但我不确定它是否真的有助于解决这个特殊问题。我的问题更具体。这是关于直接在关系中保存(创建或更新) @rap-2-h Mihkel Allorgs 参考是正确的。也可以对关系使用updateOrCreate
方法。这是最好的方法。看我的回答***.com/a/56002200/2311074
【参考方案1】:
创建和更新需要区别对待。所以先检查是否存在公司属性。
$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']);
注意hasOne()
并不能保证你会有一对一的关系,它只是告诉 Eloquent 如何创建查询。即使您有多个Company
引用同一个User
,它也可以工作,在这种情况下,当您调用$user->company
时,您将在数据库的结果数据集中获得第一个Company
。
【讨论】:
好的,谢谢。 “注意 hasOne() 并不能保证你会有一对一的关系,它只是告诉 Eloquent 如何创建查询”-> 非常有帮助,现在已经很清楚了。【参考方案2】:$user = User::findOrFail(1);
$company = $user->company ?: new Company;
$company->name = 'Test';
$user->company()->save($company);
【讨论】:
也喜欢这种方式!又快又干净! +1 :)【参考方案3】:我正在尝试保存(因此创建或更新)用户的公司
您可以使用updateOrCreate 方法完全做到这一点:
User::findOrFail(1)->company()->updateOrCreate([],['name' => 'xyz']);
updateOrCreate
的第一个参数是一个空数组,因为公司id
是由hasOne
关系$user->company()
决定的。
顺便说一句,我建议不要在 hasOne
关系中使用自动递增 id 字段。如果您在公司表中将user_id
设置为主要,则技术上不可能为一个用户创建重复的公司行。查看我的blog post 了解更多信息。
【讨论】:
以上是关于在 Laravel 中保存一对一的关系的主要内容,如果未能解决你的问题,请参考以下文章