Laravel 4.2 Красноречивая выборка конкретного пользователя и конкретной роли

#laravel-4 #eloquent

#laravel-4 #eloquent

Вопрос:

В примере Laravel Eloquent многие ко многим используется сценарий пользователей и ролей http://laravel.com/docs/eloquent#many-to-many допустим, у меня есть группа пользователей с одинаковым семейным именем «Симпсон», и я хочу, чтобы все они получили роль «Инженер». Как я могу добиться этого с помощью Eloquent? В примере используется метод «has» http://laravel.com/docs/eloquent#querying-relations но как мне выполнить запрос к базе данных для получения значения, присутствующего как в таблице пользователей, так и в таблице ролей?

Я не ищу

 User::find(1)->roles();
  

Я ищу способ сделать что-то вроде

 User::whereFamilyName('simpson')->roles()->whereName('Engineer')
  

2-й whereName будет запрашивать таблицу ролей, а не таблицу пользователей.

Ответ №1:

Если вам нужно получить пользователей с определенной ролью:

 $role = 'Engineer';

// users with family name Simpson having role Engineer
$users = User::whereFamilyName('Simpson')
      ->whereHas('roles', function ($q) use ($role) {
           $q->where('roles.name', $role); // it joins the table so you may need to use prefixed column name, otherwise you can still use dynamic whereName()
      })
      // with('roles') if needed
      ->get();
// returns Collection of User models without roles or with all roles attached to each user if needed
  

В противном случае просто объедините таблицы:

 User::whereFamilyName('Simpson')
   ->join('role_user', 'role_user.user_id', '=', 'users.id')
   ->join('roles', 'role_user.role_id', '=', 'roles.id')
   ->whereName('Engineer') // again columns name conflict may occur
   ->get(['users.*']);
  

Все значения жестко заданы здесь, чтобы было понятно.

Комментарии:

1. Спасибо deczo, как мне передать параметр в функцию закрытия в первом примере? Вместо этого инженер может быть «барменом».

2. 1 за использование whereHas . Многие люди хотят этого, но злоупотребляют этим with .

Ответ №2:

Вы можете попробовать это:

 $users = User::with(array('roles' => function($query){
    $query->whereName('Engineer');
}))->whereFamilyName('simpson')->get(); // whereFamilyName = family_name in DB
  

Надеюсь, вы правильно объявили отношения, а также убедитесь, что это roles или role в User модели для отношений с roles таблицей. Я использовал roles , потому что вы использовали его в коде вашего вопроса.

Комментарии:

1. Это будет фильтровать только объект ролей, а не основной результат. Вместо этого вы должны использовать whereHas .