I'm using Laravel 5.7 and have a one-to-one relationship between 2 eloquent models.
I have this simple function that works well, and the correct values persist to the database:
public function saveMarketingOriginInfo(Contact $contact, $data) {
$contact->marketingOrigin()->create($data);
$this->makeOtherChangesByReference($contact->marketingOrigin);
$contact->marketingOrigin->save();
return $contact->marketingOrigin;
}
However, when writing a functional test for it, I noticed that the object that it returns is stale (doesn't have the correct values in its properties).
My tests only pass if I change the return statement to return \App\Models\MarketingOrigin::find($contact->id);
.
(MarketingOrigin uses 'contact_id' as primary key.)
What am I doing wrong?
How can I return the same object that was just saved in the previous line ($contact->marketingOrigin->save();
) without making a database read query (find()
)?
Update to respond to comments:
protected $table = 'marketing_origins';//MarketingOrigin class
protected $primaryKey = 'contact_id';
protected $guarded = [];
public function contact() {
return $this->belongsTo('App\Models\Contact');
}
The test:
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');
}
This is because the relationship has not been loaded yet.
You could try
$contact->load('marketingOrigin');
to eager load the relationship: