How to use Many to Many Polymorphic Relationship in Laravel?

Many to Many Polymorphic relationship is a very interesting thing in Laravel. Lets say we want to implement tags in our site which already has stores and products in store. One tag can be grocery so which product and store is related to this tag we can get that in one line of code and we can associate stores and products with tags. This all takes minimum effort and ensures maximum performance in Laravel. Lets implement that.

This will be schema in our products migration.

Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->float('price');
            $table->text('description');
            $table->timestamps();
});

And this will be schema for stores migration.

Schema::create('stores', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('address');
            $table->timestamps();
});

And this is schema in tags schema.

 Schema::create('tags', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
});

And this is schema in taggables migration.

Schema::create('taggables', function (Blueprint $table) {
            $table->id();
	    $table->bigInteger("tag_id");
	    $table->morphs("taggable");
            $table->timestamps();
 });

Now we will add tags() method in Product model.

public function tags() {
	    return $this->morphToMany( Tag::class, 'taggable' );
}

Same tags() method we will add in Store model.

public function tags() {
	    return $this->morphToMany( Tag::class, 'taggable' );
}

And now last but not the least tag model will look like this.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Tag extends Model
{
	public function products() {
		return $this->morphedByMany(Product::class, 'taggable');
	}

	public function store() {
		return $this->morphedByMany(Store::class, 'taggable');
	}
}

Now in order to add tags we need this code which is lesser than even ten lines. Super easy.

$tag1       = new Tag;
$tag1->name = "grocery";

$tag2       = new Tag;
$tag2->name = "kids";
		
$product = Product::first();
$product->tags()->saveMany( [ $tag1, $tag2 ] );

And we can add tags to stores as well.

$tag1       = new Tag;
$tag1->name = "grocery";

$tag2       = new Tag;
$tag2->name = "kids";
		
$store= Store::first();
$store->tags()->saveMany( [ $tag1, $tag2 ] );

And if we want to retrieve tags. It is very simple.

$store->tags;
$product->tags;

I hope now you understand everything about many to many polymorphic relationships in Laravel. It is super easy and very convenient.