Syncing a many to many relationship in laravel?

laravel
manytomany

(Sayem Hossain) #1

Recently I was facing a problem regarding Eloquent manytomany relationship in laravel.

I had a requirement to create/update a role with multiple predefined permissions. So it was clearly a manytomany relationship and everything was fine. but when updating a role if someone selects an already existing permission the it throws constraintviolationexception.

And it is totally fine. it should throw this exception because some fields on Permission were unique. So what I needed Preformatted text to do is detach that permission before adding it again.

$role->perms()->detach(); or $role->perms()->disassociate();

but the problem is, if you use detach() it will fucking delete all matching child entities and you aren’t suppose to use it with manytomany relationship anyway. Good luck using sync() because you won’t find any changes for Entrust package.

So what I had to do is, create a model for that pivot table and delete that relationship. or from database

DB::table('permission_role')->where([ ['permission_id',$perm->id], ['role_id',$role->id] ])->delete();

That’s preposterous! It solves the problem but I’m not feeling so good about it.

Does anyone have any better way to do that?


(Sayem Hossain) #2

So I’ve found the way to manage permissions appropriately is, by using detachPermission() method on entrust trait.

check inputs from the form and apply permission

$permissions = Permission::all();
foreach ($permissions as $permission) {
    $checked_permission = $request->input($permission->name);
    if ($checked_permission && !$role->hasPermission($permission->name)) {
        $role->attachPermission($permission);
    } else if (!$checked_permission && $role->hasPermission($permission->name)) {
        $role->detachPermission($permission);
    }
}

That saved me from the ugly code that I wrote before.