在事件监听器中同步多对多关系(Laravel 5.7)

Posted

技术标签:

【中文标题】在事件监听器中同步多对多关系(Laravel 5.7)【英文标题】:Syncing Many to many relationship in Event Listener (Laravel 5.7) 【发布时间】:2019-06-01 06:04:47 【问题描述】:

Laravel App 有角色,每个Role 都有权限(多对多)

每个用户都有多个角色(多对多)

当Role的权限发生变化/更新时,触发事件RolePermissionsChanged,监听器代码如下:

public function handle(RolePermissionsChanged $event)

     $role_permissions=$event->role()->permissions;
     foreach ($event->role()->users as $user) 
        $user->permissions()->sync($role_permissions);
      

这必须更新permission_user 表以将角色同步给用户。触发事件时,作业失败并出现错误:

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

如果我将foreach 循环中的行更改为App\User::find($user->id)->permissions()->sync($role_permissions);,它可以工作,但我知道应该以其他方式完成。谁能指导我哪里出错了。

编辑:

下面是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;
    


【问题讨论】:

您能否将RolePermissionsChanged 课程的代码添加到您的问题中? @RossWilson,已添加。 $event-&gt;role() 来自哪里,因为我在 RolePermissionsChanged 类中没有看到 role() 方法? 我认为问题是 $event-&gt;role() 将返回一个 Collection 实例,而 foreach ($event-&gt;role-&gt;users as $user) 这应该可以工作。 它作为App\Role:class 的实例传递,如 Laravel 文档中所述。 laravel.com/docs/5.7/events#defining-listeners 【参考方案1】:

$event-&gt;role() 应该是$event-&gt;role,它是事件类中定义的公共属性,$event-&gt;role() 将其视为函数调用。

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

【讨论】:

我删除了我的答案。我认为这应该被接受。只是有一个变化:$user-&gt;permissions-&gt;sync($permission_ids); 谢谢,是的,这适用于编辑。 :) 感谢双方

以上是关于在事件监听器中同步多对多关系(Laravel 5.7)的主要内容,如果未能解决你的问题,请参考以下文章

在 laravel 中使用多对多关系同步:PostgreSQL 数据透视表不更新

Laravel 多对多同步与附加列

Laravel 多对多关系 5 个表

Laravel 多列上的多对多同步()

Laravel 5.1 中 3 个模型之间的关系(“像多对多通过”)

如何在 Laravel 5.5 中实现多个多对多关系?