Запрос связанной модели в пределах области запроса Laravel
У меня есть метод области запроса, который фильтрует результаты по модели Foo автором модели. Усложнение состоит в том, что автор не имеет прямого отношения.
Foo принадлежит к Bar and Bar принадлежит Пользователю. Если Foo принадлежал Пользователю, я мог бы просто сделать это:
public function scopeAuthorOnly($query, User $user)
{
return $query->whereuser_id($user->id);
}
Это, очевидно, не будет работать, поскольку модель Foo не имеет столбца user_id и вместо этого имеет столбец bar_id. Однако я не уверен, как я могу построить запрос таким образом, чтобы фильтр user_id.
Любые указатели?
Ответы
Ответ 1
Найдено решение:
public function scopeAuthorOnly($query, User $user)
{
$query
->join('bars', 'foos.bar_id', '=', 'bars.id')
->join('users', 'bars.user_id', '=', 'users.id')
->where('users.id', '=', $user->id);
return $query;
}
Ответ 2
Вы можете использовать whereHas()
в области видимости для запроса отношений.
Предположим, что в этой модели есть функция отношения users()
. Тогда это будет примерно так:
public function scopeAuthorOnly($query, User $user)
{
return $query->whereHas('users', function($q) use($user){
$q->where('id', $user->id);
});
}
Обновление: Вы также можете вставлять операторы whereHas
: если текущий Foo
имеет отношение с именем bar
, а bar
имеет отношение, называемое users
, оно быть следующим:
public function scopeAuthorOnly($query, User $user)
{
return $query->whereHas('bar', function($q) use($user){
return $q->whereHas('users', function($q2) use($user){
$q2->where('id', $user->id);
});
});
}
Дополнительная информация: здесь
Ответ 3
Вы также можете сделать это с помощью отношений (не прибегая к ручным объединениям):
public function scopeAuthorOnly($query, User $user)
{
$query->whereHas(array('Bar' => function($query) use($user){
$query->where('user_id', '=', $user->id);
}));
}
Изменить: теперь используйте whereHas
вместо with
(только Laravel >= 4.1). Спасибо за исправление Арды.
Изменить: в 4.2 синтаксис whereHas изменился, так что имя отношения - это параметр 1, а замыкание - это параметр 2 (а не передается как массив):
public function scopeAuthorOnly($query, User $user)
{
$query->whereHas('Bar', function($query) use($user){
$query->where('user_id', '=', $user->id);
});
}