What is the best option when naming a pivot table where one of the columns refers to a different model?

Viewed 67

I'm using Laravel and Mysql.

I'm trying to come up with a name for my pivot table where one column is a foreign key to the products table and the other column is a foreign key to the users table. I want the table name to be product_point_of_contact. I don't want to call the table product_user as that doesn't really explain what the table does. My columns would be product_id and user_id. I don't want to name the user_id column point_of_contact_id because I don't have a point_of_contacts table.

What is the convention and best option for this? Would you also create a PointOfContact model and extend it to use the User model?

2 Answers

The Laravel convention is:

To determine the table name of the relationship's intermediate table, Eloquent will join the two related model names in alphabetical order. However, you are free to override this convention. You may do so by passing a second argument to the belongsToMany method:

return $this->belongsToMany(Role::class, 'role_user');

In addition to customizing the name of the intermediate table, you may also customize the column names of the keys on the table by passing additional arguments to the belongsToMany method. The third argument is the foreign key name of the model on which you are defining the relationship, while the fourth argument is the foreign key name of the model that you are joining to:

return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id');

So, if your models are Product and User, and you name the intermediate table as product_point_of_contact, and the fk product_id and user_id.
In your User model use:

return $this->belongsToMany(Product::class, 'product_point_of_contact');

In your Product model use:

return $this->belongsToMany(User::class, 'product_point_of_contact');

And you will not need to specify the foreign keys, since these do comply with the convention.


Said that...

What is the convention and best option for this?

IMO, the one you (and your team) can understand, and makes sense in the business logic of your application. Even if you/they read the code or the name of the tables within 6 months.

Would you also create a PointOfContact model and extend it to use the User model?

Not needed, you can use the User model. What I would do here would be to name the relationship with the meaning I want to give. For example:

class Product extends Model
{
    /**
     * The product point of contact (which is an user).
     */
    public function pointOfContact()
    {
        return $this->belongsToMany(User::class, 'product_point_of_contact');
    }
}

product_user will be the best since laravel itself will create the table name in alphabetical order, i advice you use product_user.

Related