I suggest starting with following the naming conventions used by Laravel both for your tables and your columns. That way Laravel with help you with a lot of thing straight out of the box.
Access model linked to pivot table
Hi. I have two models, 'Project' and 'Study' which both have a many-to-may relationship to another model, 'Contact'. So this is a polymorphic many-to-many with a pivot table we could call 'contactables'. All fine so far. However, the contacts can have different roles in different contexts so I have a Role model that also links to the 'contactables' table in a one-to-many relationship so the schema looks like this.
$table->foreignId('contact_id')->constrained();
$table->foreignId('contactable_id');
$table->string('contactable_type', 100);
$table->foreignId('contact_role_id');
My problem is: how can I access the Role data when I'm compiling a collection of Contacts for a particular Project? Is there some way I can iterate through Investigation->contacts as $contact and say: $contact->role->name?
Well I've managed to partially solve the problem by defining a custom intermediate table model called Contactable. The relationship in the Project model is now as follows:
public function contacts()
{
return $this->morphToMany(Contact::class, 'contactable')
->using(Contactable::class)
->withPivot('contact_role_id');
}
The Contactable model has a many-to-one relationship to the ContactRole model thus:
public function role()
{
return $this->belongsTo(ContactRole::class, 'contact_role_id', 'id');
}
I can now generate a collection of contacts for a Project
$pojectcontacts = Project::find($project_id)->contacts;
and then access each contact's role in a loop using
@foreach ($projectcontacts as $projectcontact)
{{$projectcontact->pivot->role->name}}
@endforeach
I was lead to this solution by this tutorial page: https://codecheef.org/article/extra-field-with-extra-relationship-in-laravel-pivot-table-example
My only problem now is that I can't find a way to eager load the roles so I have an n+1 issue.
Please or to participate in this conversation.