In this article, we will discuss Laravel's many-to-many polymorphic relationships in laravel web application. This is the last type in chic relationships and this is a little more complicated than most relationships. For example, if you have posts, videos, and tag tables, you need to connect with each other according to your need, as each post has multiple tags and is the same for videos. As well as each tag attached to multiple posts or multiple videos. But we can easily do that using just one table "Tagables". Just read the article and you got it.
Here we can understand how to create polymorphic many-to-many relationships with migration with foreign key schema for one-to-many relationships, Polymorphic Many to Many Relationship will use "morphToMany()" and "morphedByMany()" for relation, use sync with pivot table, create records, add records, retrieve records.
Step 1 : Create Migrations
In this regard, we will need four database tables: posts, videos, tags and taggables. The item table will be linked to the posts and videos table using the tags table.
We need to create four migration tables. Run the following four commands in the terminal to create migration classes on the database / migration directory.
php artisan make:migration create_posts_table
php artisan make:migration create_videos_table
php artisan make:migration create_tags_table
php artisan make:migration create_taggables_table
posts table migration:
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string("name");
$table->timestamps();
});
videos table migration:
Schema::create('videos', function (Blueprint $table) {
$table->increments('id');
$table->string("name");
$table->timestamps();
});
tags table migration:
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->string("name");
$table->timestamps();
});
taggables table migration:
Schema::create('taggables', function (Blueprint $table) {
$table->integer("tag_id");
$table->integer("taggable_id");
$table->string("taggable_type");
});
Let's look at the migration fields. In the taggables table, We have tag_id, taggable_id and taggable_type fields. The tag_id will store id value of tags table, taggable_id will store id value of orders or videos table and taggable_type will store the Post or Tag class name like App\Models\Post or App\Models\Video.
Now run the migrate command to create tables into database.
php artisan migrate
Step 2 : Create Models
Laravel models are located at app/Models directory. Now, we also need to create the model classes for these tables using following Artisan commands one by one into Terminal.
php artisan make:model Post
php artisan make:model Video
php artisan make:model Tag
First create tags() method into Post model which will return morphToMany() method.
Post Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
/**
* Get all of the tags for the post.
*/
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
}
Video Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Video extends Model
{
/**
* Get all of the tags for the post.
*/
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
}
First create posts() and videos() method into Post model which will return morphedByMany() method.
Tag Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
/**
* Get all of the posts that are assigned this tag.
*/
public function posts()
{
return $this->morphedByMany(Post::class, 'taggable');
}
/**
* Get all of the videos that are assigned this tag.
*/
public function videos()
{
return $this->morphedByMany(Video::class, 'taggable');
}
}
Step 3 : Get Items:
Get tegs for post
/**
* Access Post Tags.
*
* @return \Illuminate\Http\Response
*/
public function getPostTags()
{
$post = Post::find(1);
dd($post->tags);
}
Get tegs for video
/**
* Access Video Commnets.
*
* @return \Illuminate\Http\Response
*/
public function getVideoTags()
{
$video = Video::find(1);
dd($video->tags);
}
Get posts by particular teg
/**
* Access Posts by particular teg.
*
* @return \Illuminate\Http\Response
*/
public function getPostTags()
{
$tag = Tag::find(1);
dd($tag->posts);
}
Get videis by particular teg
/**
* Access Videos by particular teg.
*
* @return \Illuminate\Http\Response
*/
public function getPostTags()
{
$tag = Tag::find(1);
dd($tag->videos);
}
Step 3 : Add Items:
create single tag
public function addTag()
{
$post = Post::find(1);
$tag = new Tag;
$tag->name = "ItSolutionStuff.com";
$post->tags()->save($tag);
}
public function addTag()
{
$video = Video::find(1);
$tag = new Tag;
$tag->name = "ItSolutionStuff.com";
$video->tags()->save($tag);
}
create multipal tags
public function addTag()
{
$post = Post::find(1);
$tag1 = new Tag;
$tag1->name = "ItSolutionStuff.com";
$tag2 = new Tag;
$tag2->name = "ItSolutionStuff.com 2";
$post->tags()->saveMany([$tag1, $tag2]);
}
public function addTag()
{
$video = Video::find(1);
$tag1 = new Tag;
$tag1->name = "ItSolutionStuff.com";
$tag2 = new Tag;
$tag2->name = "ItSolutionStuff.com 2";
$video->tags()->saveMany([$tag1, $tag2]);
}
Other example
$post = Post::find(1);
$tag1 = Tag::find(3);
$tag2 = Tag::find(4);
$post->tags()->attach([$tag1->id, $tag2->id]);
$video = Video::find(1);
$tag1 = Tag::find(3);
$tag2 = Tag::find(4);
$video->tags()->attach([$tag1->id, $tag2->id]);
$post = Post::find(1);
$tag1 = Tag::find(3);
$tag2 = Tag::find(4);
$post->tags()->sync([$tag1->id, $tag2->id]);
$video = Video::find(1);
$tag1 = Tag::find(3);
$tag2 = Tag::find(4);
$video->tags()->sync([$tag1->id, $tag2->id]);
I hope this will help you to understand many to many polymorphic relationship in laravel app.