Curated Prime
Curated Prime

Reputation: 57

Syncing Many to many relationship in Event Listener (Laravel 5.7)

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;
    }

}

Upvotes: 0

Views: 833

Answers (1)

Brian Lee
Brian Lee

Reputation: 18187

$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);
    });
}

Upvotes: 1

Related Questions