在 Laravel 中保存一对一关系

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32498142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 12:19:53  来源:igfitidea点击:

Saving one to one relation in Laravel

phplaraveleloquent

提问by rap-2-h

A Userhas one (or zero) Company, and a Companybelongs to one and only one User. 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 though savemethod on User.

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

So Companyhas one method user():

所以Company有一种方法user()

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

And Userhas one method company():

User有一种方法company()

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)

这是 Laravel 中的一个小故障(或者我在一对一关系中不理解的东西)还是我做错了什么?(我认为并希望这是第二个目的)

回答by PaePae

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 Companyrefer to same User, in such case when you call $user->companyyou will get first Companyin the result data set from database.

请注意,这hasOne()并不能保证您将拥有一对一的关系,它只是告诉 Eloquent 如何创建查询。即使您有多个Company引用相同User,它也能工作,在这种情况下,当您调用时,$user->company您将首先获得Company来自数据库的结果数据集。

回答by MstfAsan

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

回答by Adam

I'm trying to save (so create or update) a user's company

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

You can do exactly that with the updateOrCreatemethod:

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

User::findOrFail(1)->company()->updateOrCreate([],['name' => 'xyz']);

The first parameter of updateOrCreateis an empty array, because the companies idis determined by the hasOnerelationship $user->company().

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

And by the way, I would recommend not using an auto-increment id field in a hasOnerelationship. If you set user_idas primary in your company table, its technically not possible to create duplicate company rows for one user. Check out my blog postfor more.

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

回答by ARIF MAHMUD RANA

You are doing wrong here

你在这里做错了

$company = new Company();
$company->name = 'Test';
User::findOrFail(1)->company()->save($company);

You aren't telling which row to update

您没有告诉要更新哪一行

So your code has to be modified like this

所以你的代码必须像这样修改

$companyIdis your company to update

$companyId贵公司要更新吗

$company = new Company();
$company->name = 'Test';
User::findOrFail(1)->company()->find($companyId)->save($company);