当同一模型也存在 HasMany 关系时,如何更新 HasOne 关系?

Posted

技术标签:

【中文标题】当同一模型也存在 HasMany 关系时,如何更新 HasOne 关系?【英文标题】:How to update a HasOne relationship when a HasMany relationship also exists with the same model? 【发布时间】:2019-06-06 00:23:31 【问题描述】:

我正在尝试在 Eloquent 中的相同两个模型之间定义 both HasMany 和 HasOne 关系。

我的Organization 班级有很多Contacts:

public function contacts()

    return $this->hasMany(Contact::class);

同样,我的Contact 类反映了这种关系:

public function organization()

    return $this->belongsTo(Organization::class);

而且,每个Organization 都只有一个“主要”Contact。我正在使用表格列organizations.primary_contact_id 来识别哪一个:

public function primaryContact()

    return $this->hasOne(Contact::class, 'id', 'primary_contact_id');

从这里开始,我被困住了。 Contact 中的反向关系已经存在,所以我编写了另一个我认为可以解决问题的函数,计算如果我更新父表中的值,Eloquent 会自然地获取联系人表中的相应记录,因为我定义了关系:

/**
 * @param \App\Contact
 */
public function setPrimaryContact($contact)

    $this->primary_contact_id = $contact->id;
    $this->save;

但它没有:

>>> $org = Organization::find(17)
=> App\Organization #2923
     id: 17,
     name: "Test Org",
     primary_contact_id: 33,
   
>>> $alice= $org->primaryContact
=> App\Contact #2938
     id: 33,
     organization_id: 17,
     fname: "Alice",
     lname: "Abbot",
   
>>> $bob = Contact::find(34)
=> App\Contact #2939
     id: 34,
     organization_id: 17,
     fname: "Bob",
     lname: "Baker",
   
>>> $org->setPrimaryContact($bob)
=> null
>>> $org
=> App\Organization #2923
     id: 17,
     name: "Test Org",
     primary_contact_id: 34,
     primaryContact: App\Contact #2938
       id: 33,
       organization_id: 17,
       fname: "Alice",
       lname: "Abbot",
     ,
   

您可以看到 setPrimaryContact($bob) 执行得很好,因为 primary_contact_id 已更新为 Bob 的 id,但 primaryContact 仍然列出 Alice。

为什么primaryContact 没有返回正确的对象?

【问题讨论】:

您是在更新之前还是之后获取记录?更新完成后你能不能dd(App\Organization::find(17)->primaryContact看看你得到了什么。 【参考方案1】: 您的setPrimaryContact 方法不会更新您的表,因为您调用$this->save,而不是$this->save()save 是一种方法 在$org->setPrimaryContact($bob)之后,你应该调用$org-> primaryContact->refresh()来获取更新的记录。

【讨论】:

我将其更新为 $this->save() 并调用了 $org->primaryContact->refresh() 这不起作用,但 $org->refresh() 可以!非常感谢! 还发现我可以从setPrimaryContact() 中调用$this->refresh(),这也可以解决问题。 我很高兴它有帮助。 refresh 将更新当前模型并重新加载它的关系。

以上是关于当同一模型也存在 HasMany 关系时,如何更新 HasOne 关系?的主要内容,如果未能解决你的问题,请参考以下文章

Ember js - 更新其他表后 Hasmany 关系中断

如何在 Laravel 8 中获取与 json 有一个 hasMany 关系的表的所有模型?

同一张表上的多个关系

当更新同一模型中的另一个特定字段时,如何更新 Django models.DateTimeField?

Laravel按hasmany关系排序

如何同步hasMany关系上的子表数据?