【问题标题】:Laravel Eloquent relationship object stale even though data correct in databaseLaravel Eloquent 关系对象陈旧,即使数据库中的数据正确
【发布时间】:2018-12-10 11:03:26
【问题描述】:

我正在使用 Laravel 5.7,并且在两个 eloquent 模型之间有一个 one-to-one relationship

我有一个运行良好的简单函数,并且正确的值保存到数据库中:

public function saveMarketingOriginInfo(Contact $contact, $data) {
    $contact->marketingOrigin()->create($data);        
    $this->makeOtherChangesByReference($contact->marketingOrigin);
    $contact->marketingOrigin->save();
    return $contact->marketingOrigin; 
}

但是,在为它编写功能测试时,我注意到它返回的对象是陈旧的(其属性中没有正确的值)。

只有当我将 return 语句更改为 return \App\Models\MarketingOrigin::find($contact->id); 时,我的测试才会通过。

(MarketingOrigin 使用 'contact_id' 作为主键。)

我做错了什么?

如何在不进行数据库读取查询 (find()) 的情况下返回刚刚保存在上一行 ($contact->marketingOrigin->save();) 中的相同对象?


更新以响应 cmets:

protected $table = 'marketing_origins';//MarketingOrigin class
protected $primaryKey = 'contact_id';
protected $guarded = [];
public function contact() {
    return $this->belongsTo('App\Models\Contact');
}

测试:

public function testSaveMarketingOriginInfo() {
    $helper = new \App\Helpers\SignupHelper();
    $contactId = 92934;
    $contact = factory(\App\Models\Contact::class)->create(['id' => $contactId]);
    $leadMagnetType = 'LMT';
    $audience = 'a60907';
    $hiddenMktgFields = [
        'audience' => $audience,
        'leadMagnetType' => $leadMagnetType
    ];
    $result = $helper->saveMarketingOriginInfo($contact, $hiddenMktgFields);
    $this->assertEquals($result->contact_id, $contactId, 'contact_id did not get saved');
    $this->assertEquals($result->campaignId, '6075626793661');
    $this->assertEquals($result->leadMagnetType, $leadMagnetType);
    $marketingOrigin = \App\Models\MarketingOrigin::findOrFail($contactId);
    $this->assertEquals($marketingOrigin->adsetId, '6088011244061');
    $this->assertEquals($marketingOrigin->audience, $audience);
    $this->assertEquals($marketingOrigin, $result, 'This is the assertion that fails; some properties of the object are stale');
}

【问题讨论】:

  • 请发marketingOrigin关系和测试。
  • @JonasStaudenmeir 我按照你的要求添加了关系和测试。谢谢。

标签: laravel laravel-5 eloquent


【解决方案1】:

这是因为关系尚未加载。

你可以尝试$contact->load('marketingOrigin'); 来加载关系:

public function saveMarketingOriginInfo(Contact $contact, $data) {
    $contact->marketingOrigin()->create($data);        
    $this->makeOtherChangesByReference($contact->marketingOrigin);
    $contact->marketingOrigin->save();
    $contact->load('marketingOrigin'); // <---- eager load the relationship
    return $contact->marketingOrigin; 
}

【讨论】:

  • 有趣。你是说“加载”不会进行数据库调用?
  • 谢谢!我刚刚尝试了您的代码,并且我的测试通过了,这很棒。但我很好奇$contact-&gt;load('marketingOrigin'); 是否仍在查询数据库(因此并不比我所拥有的更好)。我真的不知道如何阅读源代码以了解它是否从 DB 中获取:github.com/laravel/framework/blob/5.7/src/Illuminate/Database/…
  • 如果你碰巧知道如何说,我很想听听。再次感谢。
  • 自我注意:现在我也遇到了 Eloquent 急切加载问题:stackoverflow.com/q/54893873/470749
猜你喜欢
  • 2021-03-21
  • 2016-12-06
  • 2016-05-25
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多