2017-09-04 82 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;

,這將返回一個管理員的權限數組/集合..