skip to Main Content

Let’s say I have a posts and users models, I want to manage the relationship between them like so:

  • bookmarks (A post can be bookmarked by many users and vice-verca)
  • likes (Same idea as bookmarks)

The convention is to make a pivot table named post_user but in this case we have two so do I make two tables one for each relationships or is there a way to put both relationships in the same table.

I also would like to follow laravel conventions as much as possible so naming the pivot something other than post_user sounds like a bad idea

I obviously can’t make two tables both with the same name so that’s out of the question

2

Answers


  1. You don’t have to make two tables, in laravel conventions you can add more columns to the pivot table, here is an example:
    In Post model:

    public function users()
    {
        return $this->belongsToMany(User::class, 'post_user')
            ->withPivot([
                'liked'
            ])->using(PostUser::class);
    }
    

    In User model:

    public function posts()
    {
        return $this->belongsToMany(Post::class, 'post_user')
            ->withPivot([
                'liked',
            ])->using(PostUser::class);
    }
    

    Then you can fill it like the following:

    $user->posts()->attach($post, [
        'liked' => true, // false
    ]);
    // OR
    $post->users()->attach($user, [
        'liked' => true, // false
    ]);
    
    Login or Signup to reply.
  2. Yes you can achieve both relationships in the same table.
    When you create pivot table post_user you can have add a type column to indicate the relationship type.
    Post Model would be

    public function users() {
        return $this->belongsToMany(User::class, 'post_user')
            ->wherePivot('type', 'bookmark')
            ->withTimestamps();
    }
    
    public function likedByUsers() {
        return $this->belongsToMany(User::class, 'post_user')
            ->wherePivot('type', 'like')
            ->withTimestamps();
    }
    
    

    Here you are using a single pivot table but differentiating between "bookmarks" and "likes" based on the type column’s value and also maintaining Laravel conventions but this can be done with 2 pivot tables as well. Depends upon how you want to handle it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search