2015-09-16 2 views
1

Я создаю систему, в которой есть пользователи. У пользователей есть роли, а роли - действия. Мои модели настроены так:Laravel вложенные отношения, где

Пользователь

/** 
* The roles that belong to the user. 
* 
* @return Object 
*/ 
public function roles() 
{ 
    return $this->belongsToMany('App\Models\User\Role')->withTimestamps(); 
} 

Роль

/** 
* The actions that belong to the role. 
* 
* @return Object 
*/ 
public function actions() 
{ 
    return $this->belongsToMany('App\Models\User\Action')->withPivot('path'); 
} 

/** 
* The users that belong to the role. 
* 
* @return Object 
*/ 
public function users() 
{ 
    return $this->belongsToMany('App\Models\User\User'); 
} 

Действие

/** 
* The roles that belong to the action. 
* 
* @return Object 
*/ 
public function roles() 
{ 
    return $this->belongsToMany('App\Models\User\Role'); 
} 

Я пытаюсь выполните следующие действия:

$user->whereHas('roles.actions', function($query) use ($id, $path, $method){ 
     $query->where('user.id', $id); 
     $query->where('action.path', $path); 
     $query->where('action.method', $method); 
})->get(); 

Однако по какой-либо причине возвращенный объект пуст (строки не возвращаются). Если я удалю $query->where('action.path', $path);, он работает, но это бессмысленно, потому что мне нужна эта часть.

SQL, который получает генерируемый:

select * from `user` 
    where `user`.`cust_id` = 1 
    and (
      select count(*) from `role` 
      inner join `role_user` on `role`.`id` = `role_user`.`role_id` 
      where `role`.`cust_id` = 1 
      and `role_user`.`user_id` = `user`.`id` 
      and 
      (
       select count(*) from `action` 
       inner join `action_role` on `action`.`id` = `action_role`.`action_id` 
       where `action`.`cust_id` = 1 
       and `action_role`.`role_id` = `role`.`id` 
       and `user`.`id` = 1 
       and `action`.`path` = '/admin/users/administrators/{id}/changePassword' 
       and `action`.`method` = 'GET' 
       and `action`.`cust_id` = 1 
      ) >= 1 
      and `role`.`cust_id` = 1 
     ) >= 1 

Мои пользователи таблица содержит следующие данные:

id cust_id name 
1  1   John Smith 

Моя таблица действий содержит следующие данные:

id cust_id path            method 
1  1   /admin/users/administrators/{id}/changePassword GET 

Почему это не работает?

+0

Используя мой ответ [здесь] (http://stackoverflow.com/questions/32551662/laravel-5-1-users-roles-and-actions/32593899#32593899), и я полагаю, что это было полезно, но didn «Подумайте об увеличении». :( –

+0

Что имеет переменная '$ user', это' App \ User :: all() '? –

ответ

1

Я не очень понимаю, как это допустимый запрос, потому что вы запрашиваете на колонке в таблице users в подзапрос, который не присоединяющиеся ни на что, относящихся к пользователям.

Попробуйте это вместо этого.

$user->whereHas('roles.actions', function($query) use ($path, $method){ 
    $query->where('path', $path); 
    $query->where('method', $method); 
})->find($id); 
0

удалить ->withPivot('path'); и попробуйте еще раз

0

Как отметил в своем вопросе, а другой один HEREpath НЕ дополнительный атрибут вашей сводной таблицы action_role - проведение взаимосвязи между моделями Role и Action.

Вместо этого это атрибут таблицы action. Следовательно, используя withPivot('path'), вы определяете дополнительный атрибут на pivot (т. Е. action_role), который не существует и, следовательно, вовсе не нужен.

Относительно пустой набор вы получите, если вы включите строку $query->where('action.path', $path), наиболее вероятной причиной является то, что неправильно ИЛИ null значение предоставляется в вашей $path переменной. Дважды проверьте, имеет ли он правильное значение.


Примечание:Насколько я знаю, вы не можете выполнить whereHas на $user подобное (хотя я не совсем уверен, что это имеет место). Даже если $user представляет собой совокупность пользователей (получено App\Models\User::all()), соответствующий подход к использованию whereHas является использование его в качестве модели, как App\User::whereHas(... или его вместе с отношением.