通过belongsToMany远离属于ToMany

时间:2017-09-04 19:14:40

标签: php laravel eloquent relationship

我试图抓住一段遥远的关系而且它不起作用。我尝试过hasManyThrough,但似乎不适用于belongsToMany关系。它抛出了一个查询错误。

以下是我的迁移:

    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
    });

    Schema::create('roles', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->timestamps();
    });


    Schema::create('role_user', function (Blueprint $table) {
        $table->integer('role_id');
        $table->integer('user_id');
    });

    Schema::create('permissions', function (Blueprint $table) {
        $table->increments('id');
        $table->string('group');
        $table->string('name');
        $table->timestamps();
    });

    Schema::create('permission_role', function (Blueprint $table) {
        $table->integer('permission_id');
        $table->integer('role_id');
    });

以下是我的模特:

class User extends AuthUser
{
    //

    public function roles()
    {
        return $this->belongsToMany('App\Role');
    }
}

class Role extends Model
{
    //

    public function permissions()
    {
        return $this->belongsToMany('App\Permission');
    }
}

我想做的事情:

$user = App\User::find(1);
Log::info($user->roles->permissions);

这给了我Property [permissions] does not exist on this collection instance.错误。

如何通过角色获取用户权限?

修改

我已经想出了这个丑陋的解决方案来解决我想要做的事情:

if (auth()->check()) {
    if (auth()->user()->roles->contains('name', 'Admin')) {
        Gate::before(function () {
            return true;
        });
    }
    else {
        $permissions = [];

        foreach (auth()->user()->roles as $role) {
            $permissions = array_merge($permissions, $role->permissions->pluck('name')->all());
        }

        foreach (array_unique($permissions) as $permission) {
            Gate::define($permission, function () {
                return true;
            });
        }
    }
}

我该如何改善这个?

4 个答案:

答案 0 :(得分:1)

你应该急切地加载这样的关系:

$user = User::with(['roles', 'roles.permissions'])->where('id', 1)->first();

这将为您提供一系列角色,以及每个角色及其各自的权限。

Permission::whereHas('role', function($query) use ($user_id) {
    return $query->whereHas('user_id', $user_id);
});

上述查询中的想法是,当您需要多个远程关系时,you work backwards

答案 1 :(得分:0)

更改$ user = App \ USER-> find(1);

对此 $ user = App \ User :: find(1);

试试这会对你有用

答案 2 :(得分:0)

您没有在迁移中设置外键 $表 - >外国(' ROLE_ID) - >引用(' ID') - >在('作用&#39);

用户的相同定义

答案 3 :(得分:0)

它给出了Property [permissions] does not exist on this collection instance.错误,因为:$user->roles返回一组角色,而模型中的permissions仅用于单个模型。

基本上,您必须foreach($user->roles as $role)才能使用$role->permissions

但是这里有一个样本,你不必根据角色来获得许可。

auth()->user()->roles->where('name','=','Administrator')->permissions;

这将返回管理员的数组/权限集合。