Search code examples
laravellaravel-5laravel-5.7

Use pivot table for extra attributes?


I am following the many to many relationships Laravel tutorial here on Laracasts - https://laracasts.com/series/laravel-5-fundamentals/episodes/21

My challenge to myself is, I have created the pivot table article_tag to keep track of the many to many relations. Articles can have many tags, and tags can have many articles. So I can run sync etc to associate tagX tagY tagZ to article1. However I also want to be able to optionally set one of the associated tags as "isGreenTag". Can I do this within the pivot table that is keeping track of the many-to-many relations? Could I add a column "is_green_tag"?

Here is my Article class relationship:

class Article extends Model {
   public function tags() {
      return $this->belongsToMany('App\Tag')->withTimestamps();
   }
}

Here is my Tag class relationship:

class Tag extends Model {
   public function articles() {
      return $this->belongsToMany('App\Articles');
   }
}

Here is my migration for the pivot table:

public function up() {
    Schema.create('article_tag', function(Blueprint $table) {
        $table->integer('article_id')->unsigned()->index();
        $table->foreign('article_id')->references('id')->on('articles')->onDelete('cascade');

        $table->integer('tag_id')->unsigned()->index();
        $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');

        $table->timestamps();
    });
}

Can I add to the pivot table migration $table->boolean('is_green_tag')->nullable()?


Solution

  • Yes you can, you can give it a default of 0 instead of making it nullable:

    $table->boolean('is_green_tag')->default(0);
    

    And then you can modify the relationship on Article class:

    public function tags() {
        return $this->belongsToMany('App\Tag')->withPivot(['is_green_tag'])->withTimestamps();
    }
    

    Once you have an Article object, you can access that property:

    foreach ($article->tags as $tag) {
        if ($tag->pivot->is_green_tag) {
            // some logic here
        }
    }
    

    To save is_green_tag for a $tagId:

    $article->tags()->attach($tagId, ['is_green_tag' => 1]);
    

    Laravel docs:
    https://laravel.com/docs/5.7/eloquent-relationships#many-to-many https://laravel.com/docs/5.7/eloquent-relationships#updating-many-to-many-relationships