entrust icon indicating copy to clipboard operation
entrust copied to clipboard

attachPermission(s) is attaching instead of syncing

Open KevinMeeuwisse opened this issue 8 years ago • 7 comments

Hi,

At the moment I'm developing a GUI around this Entrust module in Laravel 5.1.24.

In the documentation I read the following:

$admin->attachPermission($createPost); // equivalent to $admin->perms()->sync(array($createPost->id)); $owner->attachPermissions(array($createPost, $editUser)); // equivalent to $owner->perms()->sync(array($createPost->id, $editUser->id));

But when I dit this multiple times with the same role & permission:

$role->attachPermission($permission);

It gives me this:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2-1' for key 'PRIMARY' (SQL: insert into `permission_role` (`permission_id`, `role_id`) values (2, 1))

After I checked the EntrustRoleTrait.php I saw that the attachPermissionfunction is using attach() instead of Laravels sync() method.

I was wondering if this is a bug in the documentation or RoleTrait? https://github.com/Zizaco/entrust/blob/master/src/Entrust/Traits/EntrustRoleTrait.php#L153

KevinMeeuwisse avatar Nov 25 '15 10:11 KevinMeeuwisse

Im also having this issue.

xitude avatar Dec 07 '15 11:12 xitude

Replacing

$this->perms()->attach($permission);

with

if(!$this->perms->contains('id',$permission))
    $this->perms()->attach($permission);

in EntrustRoleTrait fixed it for me. You can just add this to your Role class.

public function attachPermission($permission)
{
    if (is_object($permission)) {
        $permission = $permission->getKey();
    }

    if (is_array($permission)) {
        $permission = $permission['id'];
    }

    if(!$this->perms->contains('id',$permission))
        $this->perms()->attach($permission);
}

Hope it helps ;)

EcoFreak avatar Feb 02 '16 01:02 EcoFreak

This may be old, but I have recently run into the same problem. Here is what I did.

Before $role->attachPermission($permission);

After

if (!$role->perms()->get()->contains('id', $permission->id)) {
	$role->attachPermission($permission);
}

Hope this helps you guys.

ryanicle avatar Jan 23 '17 08:01 ryanicle

This is an old thread, I had the same error, but it's because copied/paste the doc without reading the specifics.

I had :

        $user = User::where('email', '=', '[email protected]')->first();
        $user->attachRole($admin); // parameter can be an Role object, array, or id
        $user->roles()->attach($admin->id); // id only

So I was attaching the role twice which caused the issue.

Hope it saves some time to someone in the futur :)

villeneuve-michael avatar Jun 09 '17 17:06 villeneuve-michael

This solved it for me, I just added a condition to check whether the role was not assigned already.

$admin = Role::where('name', 'manager')->get()->first();

            if (!$user->hasRole('manager')) {
                // Attach role manager
                $user->attachRole($admin);
            }

salmonerasmus avatar Jul 04 '17 17:07 salmonerasmus

I think that:

$admin->attachPermission($createPost);
// not equivalent to $admin->perms()->sync(array($createPost->id));

If you using:

$role->attachPermission($permission);

you will give errors: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2-1' for key 'PRIMARY' (SQL: insert into permission_role (permission_id, role_id) values (2, 1))

I was resolved it:

$admin->perms()->sync(array($createPost));
The similar:

$user->roles()->sync(array($roles));

Sasuka avatar Nov 20 '19 08:11 Sasuka

@ryanicle thank you. your solution works well with me

AmrAbdalrahman avatar Jun 18 '20 16:06 AmrAbdalrahman