0

Laravel App has roles and each Role has permissions (many to many)

Each user has multiple roles (Many to many)

When the permissions of Role are changed/updated, Event RolePermissionsChanged is triggered and the listener has following code:

public function handle(RolePermissionsChanged $event)
{
     $role_permissions=$event->role()->permissions;
     foreach ($event->role()->users as $user) {
        $user->permissions()->sync($role_permissions);
      }
}

This has to update permission_user table to sync the roles to the user. When the event is triggered, the job fails with an error:

Method Illuminate\Database\Eloquent\Collection::sync does not exist.

If I change the line in foreach loop to App\User::find($user->id)->permissions()->sync($role_permissions);, it is working but I know it should be done the other way. Can anyone guide where I am going wrong.

Edit:

Below is RolePermissionsChanged::class

<?php

namespace App\Events\Auth;

use Illuminate\Queue\SerializesModels;
use Illuminate\Foundation\Events\Dispatchable;
use App\Role;

class RolePermissionsChanged
{
    use Dispatchable, SerializesModels;

    public $role;

    public function __construct(Role $role)
    {
        $this->role=$role;
    }

}

1 Answers1

1

$event->role() should be $event->role, it's a public property defined in the event class, where $event->role() is treating it as a function call.

public function handle(RolePermissionsChanged $event)
{
    $permission_ids = $event->role->permissions->pluck('id')->toArray();

    $event->role->users->each(function (User $user) use ($permission_ids) {
        $user->permissions()->sync($permission_ids);
    });
}
Brian Lee
  • 17,904
  • 3
  • 41
  • 52