2017-09-04 37 views
1

我想抓住一个遥远的关系,它不工作。我试过做hasManyThrough,但这似乎不适用于belongsToMany关系。这是抛出查询错误。越来越远belongsToMany通过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; 
      }); 
     } 
    } 
} 

我该如何提高呢?

+0

用户和角色有多对多的关系? –

+0

你的关系是什么样的?它是一个用户有多个角色,这些角色有很多权限? –

+0

@ImmortalDude是的。 – kjdion84

回答

0

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

to this $ user = App \ User :: find(1);

尝试这为你工作

+0

我的问题有一个错字。它已经是'App \ User :: find(1)'。这是行不通的。 – kjdion84

0

您还没有设置外键迁移 $表 - >外国( 'ROLE_ID) - >引用(' ID ') - 上>(' 角色);

同样为用户定义

+1

外键不能解决问题。关系不需要设置外键。我还添加了外键并尝试了它,结果是一样的。 – kjdion84

+0

完成更改后,php工匠迁移 – Abhishek

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

+0

你可以看看OP。我在编辑我想要做的事情时展示了一些示例代码。我现在基本上试图重构代码,所以它不那么低劣。有小费吗? – kjdion84

+0

你也可以提供背后的推理吗?正如你的例子可能有效,但让OP理解他的推理失败的原因,以及为什么聚合不适用于多对多到多对多的关系:P – Merv

0

它给了你Property [permissions] does not exist on this collection instance.错误,因为:$user->roles返回角色的集合,而permissions模型中的作用仅仅是为了单个模型..

基本上你必须foreach($user->roles as $role)才可以使用$role->permissions

但这里是一个示例,你没有的foreach得到取决于角色权限..

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

,这将返回一个管理员的权限数组/集合..