Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

gvdspuy's avatar
Level 51

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?

0 likes
5 replies
Tray2's avatar

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.

gvdspuy's avatar
Level 51

@tray2 As far as I can tell, all my naming follows Laravel conventions. You're welcome to point out anything you think is non-standard.

Tray2's avatar

@gvdspuy This pivot doesn't follow standard naming

So this is a polymorphic many-to-many with a pivot table we could call 'contactables'.

gvdspuy's avatar
Level 51

@Tray2 That is what it is called as I mentioned in my original post.

gvdspuy's avatar
gvdspuy
OP
Best Answer
Level 51

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.