Jose Jimenez
Jose Jimenez
Software Architect & Developer
> >

Laravel Get All Morphs for a Many To Many Polymorphic Relationship

Published in Laravel, PHP on May 7, 2020

As of Laravel version 7, if you are doing Many to Many (Polymorphic) relations with Laravel via the docs here. That will give the ability to fetch $video->tags and $post->tags as well as the inverse which would be $tag->videos and $tag->posts. But what if you wanted to grab all videos and posts $tag->videosAndPosts?

Pivot Model Structure

To achieve this, you can create an intermediate Model Pivot table that will allow you to return all morphs from a tag.

1$ artisan make:model -p Taggable

This will create a Pivot Model called Taggable. We are going to overwrite the table name to match that of the pivot, as well as create a method to match that of the morph name for simplicity.

 1<?php
 2 
3namespace App;
 4 
5use Illuminate\Database\Eloquent\Relations\Pivot;
 6 
7class Taggable extends Pivot
 8{
9 protected $table = 'taggables';
10 
11 public function taggable()
12 {
13 return $this->morphTo();
14 }
15}

Model Structure

Now we need to create the mapping from our Tag Model.

1namespace App;
 2 
3use Illuminate\Database\Eloquent\Model;
 4 
5class Tag extends Model
 6{
7 /**
8 * Get all of the videos/posts that are assigned this tag.
9 */
10 public function videosAndPosts()
11 {
12 return $this->hasMany(Taggable::class);
13 }
14}

Returning results

We can now return all videos and posts

1$tag = App\Tag::find(1);
2
3foreach ($tag->videosAndPosts as $videoOrPost) {
4 //
5}

We can also use with() to minimize queries

1$tag = App\Tag::with('videosAndPosts.taggable')->find(1);
2
3foreach ($tag->videosAndPosts as $videoOrPost) {
4 //
5}