在 Laravel 中保存一对一的关系

Posted

技术标签:

【中文标题】在 Laravel 中保存一对一的关系【英文标题】:Saving one to one relation in Laravel 【发布时间】:2015-12-06 12:28:52 【问题描述】:

User 有一个(或零)CompanyCompany 属于一个且仅一个 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 中保存一对一的关系的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 laravel 8 同时保存一对多关系数据

Laravel - 一对多关系上的保存方法的对立面是啥?

Laravel 不保存一对多关系

Laravel Eloquent - 保存/更新相关的一对多关系数据

Laravel 关系中一对一关系的视图中显示

Laravel SUM 一对多(逆)/属于关系