Я пытаюсь получить доступ к дочерним объектам вложенных отношений, которые возвращают много результатов от объекта parent.Laravel: запрос и доступ к дочерним объектам в вложенных отношениях с where clauses
Скажем, у меня есть 4 модели: Страна - провинций - Города - Муниципалитеты
их отношения следующим образом:
Страна Модель
class Country extends Eloquent
{
protected $table = 'countries';
public function provinces()
{
return $this->hasMany('Province');
}
}
провинция Модель
class Province extends Eloquent
{
protected $table = 'provinces';
public function cities()
{
return $this->hasMany('City');
}
public function country()
{
return $this->belongsTo('Country');
}
}
Город Модель
class City extends Eloquent
{
protected $table = 'cities';
public function municipalities()
{
return $this->hasMany('Municipality');
}
public function province()
{
return $this->belongsTo('Province');
}
}
Самоуправление Модель
class Municipality extends Eloquent
{
protected $table = 'municipalities';
public function cities()
{
return $this->belongsTo('City');
}
}
Теперь то, что я пытаюсь сделать, это получить все муниципалитеты в данной стране, которые имеют население более 9000 и расположены в провинциях которые считаются Западом.
До сих пор у меня есть что-то вроде этого:
$country_id = 1;
$country = Country::whereHas('provinces', function($query){
$query->where('location', 'West');
$query->whereHas('cities', function($query){
$query->whereHas('municipalities', function($query){
$query->where('population', '>', 9000);
});
});
})->find($country_id);
Теперь я могу легко получить провинции с $country->provinces
, но я не могу пойти глубже, чем это.
EDIT1: Фиксировать принадлежность к отношениям, как заметил Ярек.
EDIT2: В дополнение к ответу Ярека, я хотел поделиться тем, что я также нашел, но, возможно, более подходящий метод Ярека.
Вместо того, чтобы пытаться идти сверху вниз (Страна -> Самоуправление) я решил попробовать другой путь (муниципалитет -> Страна) Вот как это работает (и я проверял, также работает)
$municipalities = Municipality::where('population', '>', 9000)
->whereHas('city', function($q) use ($country_id){
$q->whereHas('province', function($q) use ($country_id){
$q->where('location', 'West');
$q->whereHas('country', function($q) use ($country_id){
$q->where('id', $country_id);
});
});
})->get();
Я понятия не имею, если это действительно правильный способ или если производительность будет принята, но, похоже, это трюк для меня, однако ответ Джарека выглядит более элегантным.
Спасибо! Это то, что я искал, но не мог понять. В то же время я также вычислил другой способ сделать это, и это должно было фильтровать снизу вверх. Я уточню свой вопрос, чтобы отразить то, что я нашел. – sholmes
Я также хотел отметить, что интересно, что вы можете идти только на 3 уровня гнездования, и теперь, когда я знаю, я могу обойти это. – sholmes
Да, вы можете сделать это наоборот, используя 'whereHas'. Это хороший способ, просто зависит от ваших потребностей. В любом случае, я не понимаю, что вы подразумеваете под 3 уровнями гнездования? –