sanjay ojha
sanjay ojha

Reputation: 537

How to use many to many polymorphic relation in Laravel 5.2

I am reading laravel 5.2 docs to implement many to many polymorphic relation in my Laravel Application. I have Many models like Blog, Question, Photo etc and I want to have Tagging system for all of them. I have created Tag table with following schema

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

Below is pivot table schema. Pivot table name is entity_tags

Schema::create('entity_tags', function (Blueprint $table) {
     $table->increments('id');
     $table->integer('tag_id')->unsigned();;
     $table->integer('taggable_id')->unsigned();
     $table->string('taggable_type');
     $table->timestamps();
     $table->index('tag_id');
     $table->index('taggable_id');
     $table->index('taggable_type');
});

This is the relationship defined in Tag model for Question model

public function questions()
{
    return $this->belongsToMany('App\Question', 'entity_tags', 'tag_id', 'taggable_id');
}

And the following relation is defined in Question Model

public function tags()
{
    return $this->belongsToMany('App\Tag', 'entity_tags', 'taggable_id', 'tag_id');
}

Now I want to define Many to Many Polymorphic relationship as defined in Laravel 5.2.
My Question are

Upvotes: 9

Views: 5154

Answers (1)

Davor Minchorov
Davor Minchorov

Reputation: 2076

  • Use return $this->morphToMany() instead of belongsToMany, and in the Tag model, write 3 methods with return $this->morphedByMany() for the reverse relationship.

  • You only need polymorphic definitions, no need for the many to many normal ones. The name of the pivot table is with 'able' at the end by the default convention but you can name it anything you want.

  • no, you don't have to have a word with 'able' at the end, it's just a way to define that it's something more general, you can name it anything you want.

Naming is based on some default convention by Laravel.

Update:

You have the following pivot table schema:

Schema::create('entity_tags', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('tag_id')->unsigned();;
        $table->integer('entity_id')->unsigned();
        $table->string('entity_type');
        $table->timestamps();
        $table->index('tag_id');
        $table->index('entity_id');
        $table->index('entity_type');
});

and the tags table:

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

So you want to create the relationships for blog, video and question tables / models:

Tag.php Model:

public function questions()
{
    return $this->morphedByMany('App\Question', 'entity', 'entity_tags');
}

public function blogs()
{
    return $this->morphedByMany('App\Blog', 'entity', 'entity_tags');
}

public function videos()
{
    return $this->morphedByMany('App\Video', 'entity', 'entity_tags');
}

Question.php / Blog.php / Video.php

public function tags()
{
    return $this->morphToMany('App\Tag', 'entity', 'entity_tags');
}

Upvotes: 10

Related Questions