在Laravel中保存一对一的关系

rap*_*2-h 14 php laravel eloquent

A User有一个(或零)Company,一个Company属于一个且只有一个User.我尝试为用户保存公司,但每次重新触发保存方法时,它都会在数据库中添加一个新条目.这是一对一的关系,所以我通过save方法User.

所以,Company有一个方法user():

public function user() {
    return $this->belongsTo(User::class, 'user_id');
}
Run Code Online (Sandbox Code Playgroud)

User有一种方法company():

public function company() {
    return $this->hasOne(Company::class, 'user_id');
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试保存(如此创建或更新)这样的用户公司(在Controller中):

$company = new Company();
$company->name = 'Test';
User::findOrFail(1)->company()->save($company);
Run Code Online (Sandbox Code Playgroud)

我第一次运行此代码时会在数据库中创建条目(OK),但第二次为同一用户添加新条目(不正常).我以为它只会更新数据库条目.

在Laravel中,这是一个小问题(或者我在一对一关系中不理解的事情),还是我做错了什么?(我想并希望这是第二个目的)

小智 21

创建和更新需要区别对待.因此,首先检查公司属性的存在.

$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']);
}
Run Code Online (Sandbox Code Playgroud)

请注意,hasOne()这不保证您将具有一对一的关系,它只是告诉Eloquent如何创建查询.即使您有多个Company引用相同也是有效的User,在这种情况下,当您调用时,您将从数据库中获得结果数据集中的$user->company第一个Company.


Mst*_*san 14

$user = User::findOrFail(1);
$company = $user->company ?: new Company;
$company->name = 'Test';
$user->company()->save($company);
Run Code Online (Sandbox Code Playgroud)


Ada*_*dam 10

我正在尝试保存(因此创建或更新)用户的公司

您可以使用updateOrCreate方法做到这一点

User::findOrFail(1)->company()->updateOrCreate([],['name' => 'xyz']);
Run Code Online (Sandbox Code Playgroud)

的第一个参数updateOrCreate是一个空数组,因为公司id是由hasOne关系决定的$user->company()

顺便说一下,我建议不要在hasOne关系中使用自动递增的 id 字段。如果您user_id在公司表中设置为主,则技术上不可能为一个用户创建重复的公司行。查看我的博客文章了解更多信息。