Reputation: 2869
Contrived example: go!
Say I have a Dog
.
This Dog
can be owned by User
s and Company
s, any number of each. (It's a lovable dog).
So we're working with 5 tables so far:
Now, to complicate things, each pivot table has an extra field or two. Let's say the the Companies track the dog's shot records is_shotted
and the Users track his feeding is_fed
.
Assuming I have the relationships set up properly on User, Company, and Dog, I can do:
$users->dogs()->first()->pivot->is_fed
to access one pivot table and
$companies->dogs()->first()->pivot->is_shotted
to access the other.
But how do I access both? I want a way to retroactively "activate" a relationship. Something like this only better:
$dog = $users->dogs->first();
$is_fed = $dog->pivot->is_fed;
$dog->addPivot( $company );
$is_shotted = $dog->pivot->is_shotted;
Is there any way to do this without doing raw DB queries on the pivot table? I really want to avoid that, it makes things very messy sometimes.
As an consolation alternative: is there a "right" way to add data onto a model, properties that aren't on the table, that will persist through the request and will still be toArray()
ed? (I can modify the accessor if needed.)
Upvotes: 0
Views: 1023
Reputation: 7371
Once you have the $dog
object, call your dog_company
inverse relation, i.e. $dog->companies()->first()->pivot->is_shotted
to work backwards from dog up to company. Or if the dog can belong to multiple companies, $dog->companies
would retrieve them all, and you would need to decide which company to check is_shotted
on.
If you need to retrieve is_shotted
and is_walked
as part of one result collection, you could use an accessor and merge the two relations. So, for instance, starting from the dog
model, you could:
public function getOwnersAttribute($value)
{
$ownerUser = $this->users;
$ownerCompany = $this->company;
// Return a single collection result
return $ownerUser->merge($ownerCompany);
}
or, tacking additional methods on to the relations:
public function getOwnersAttribute($value)
{
$ownerUser = $this->users()->latest()->get();
$ownerCompany = $this->company()->latest()->get();
// Return a single collection result
return $ownerUser->merge($ownerCompany);
}
I would imagine you could modify this accessor to go from user
->
dog
->
company
and merge the result into a single collection, but I haven't tested that.
Upvotes: 1