Laravel Many To Many


Example

Lets say there is roles and permissions. Each role may belongs to many permissions and each permission may belongs to many role. so there will be 3 tables. two models and one pivot table. a roles, users and permission_role table.

Role Model

public function permissions()
{
   return $this->belongsToMany(Permission::class);
}

Permission Model

public function roles()
{
   return $this->belongsToMany(Roles::class);
}

Note: 1

consider following while using different table name for pivot table.

Suppose if you want to use role_permission instead of permission_role, as eloquent uses alphabetic order for building the pivot key names. you will need to pass pivot table name as second parameter as follows.

Role Model

public function permissions()
{
   return $this->belongsToMany(Permission::class, 'role_permission');
}

Permission Model

public function roles()
{
   return $this->belongsToMany(Roles::class, 'role_permission');
}

Note: 2

consider following while using different key names in pivot table.

Eloquent assumes that if no keys are passed as third and fourth parameters that it will be the singular table names with _id. so it assumes that the pivot will be having role_id and permission_id fields. If keys other than these are to be used it should be passed as third and fourth parameters.

Lets say if other_role_id instead of role_id and other_permission_id instead of permission_id is to be used. So it would be as follows.

Role Model

public function permissions()
{
   return $this->belongsToMany(Permission::class, 'role_permission', 'other_role_id', 'other_permission_id');
}

Permission Model

public function roles()
{
   return $this->belongsToMany(Roles::class, 'role_permission', 'other_permission_id', 'other_role_id');
}

Accessing Intermediate table using withPivot()

Suppose you have a third column 'permission_assigned_date' in the pivot table . By default, only the model keys will be present on the pivot object. Now to get this column in query result you need to add the name in withPivot() function.

   public function permissions()
        {
           return $this->belongsToMany(Permission::class, 'role_permission', 'other_role_id', 'other_permission_id')->withPivot('permission_assigned_date');
        }

Attaching / Detaching

Eloquent also provides a few additional helper methods to make working with related models more convenient. For example, let's imagine a user can have many roles and a role can have many permissions. To attach a role to a permission by inserting a record in the intermediate table that joins the models, use the attach method:

$role= App\Role::find(1);    
$role->permissions()->attach($permissionId);

When attaching a relationship to a model, you may also pass an array of additional data to be inserted into the intermediate table:

$rol->roles()->attach($permissionId, ['permission_assigned_date' => $date]);

Similarly, To remove a specific permission against a role use detach function

$role= App\Role::find(1);
//will remove permission 1,2,3 against role 1
$role->permissions()->detach([1, 2, 3]);

Syncing Associations

You may also use the sync method to construct many-to-many associations. The sync method accepts an array of IDs to place on the intermediate table. Any IDs that are not in the given array will be removed from the intermediate table. So, after this operation is complete, only the IDs in the given array will exist in the intermediate table:

//will keep permission id's 1,2,3 against Role id 1

$role= App\Role::find(1)
$role->permissions()->sync([1, 2, 3]);