Próbuję uzyskać dostęp do obiektów podrzędnych relacji zagnieżdżonych, które zwracają wiele wyników z obiektu nadrzędnego.Laravel: Wykonywanie zapytań i uzyskiwanie dostępu do obiektów podrzędnych w relacji zagnieżdżonej z klauzulami, gdzie klauzule
Powiedzmy mam 4 modele: Kraj - prowincje - Miasta - Gminy
ich relacje są następujące:
Kraj Model
class Country extends Eloquent
{
protected $table = 'countries';
public function provinces()
{
return $this->hasMany('Province');
}
}
Prowincja model
class Province extends Eloquent
{
protected $table = 'provinces';
public function cities()
{
return $this->hasMany('City');
}
public function country()
{
return $this->belongsTo('Country');
}
}
Miasto model
class City extends Eloquent
{
protected $table = 'cities';
public function municipalities()
{
return $this->hasMany('Municipality');
}
public function province()
{
return $this->belongsTo('Province');
}
}
Gmina model
class Municipality extends Eloquent
{
protected $table = 'municipalities';
public function cities()
{
return $this->belongsTo('City');
}
}
Teraz co próbuję zrobić, to wszystkie gminy w danym kraju, które mają populację ponad 9000 i znajdują się w prowincjach które są uważane za Zachód.
tej pory mam coś takiego:
$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);
Teraz mogę łatwo uzyskać prowincjach $country->provinces
ale nie mogę iść głębiej.
EDIT1: Naprawianie relacji belongsTo zauważonej przez Jarka.
EDIT2: Oprócz odpowiedzi Jarka, chciałem podzielić się tym, co również znalazłem, jednak metoda Jarka jest prawdopodobnie bardziej odpowiednią metodą.
Zamiast próbować iść od góry do dołu (kraj -> Gmina) postanowiłem spróbować w inny sposób (gmina -> Country) Oto jak to działa (i przetestowane, działa również)
$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();
Nie mam pojęcia, czy jest to właściwy sposób, czy też występ byłby akceptowany, ale wydawało się, że to dla mnie działka, jednak odpowiedź Jarka wygląda bardziej elegancko.
Dziękujemy! Tego właśnie szukałem, ale nie mogłem tego rozgryźć. W tym samym czasie wymyśliłem inny sposób, aby to zrobić i miałam filtrować od dołu. Zaktualizuję moje pytanie, aby odzwierciedlić to, co znalazłem. – sholmes
Chciałbym również zauważyć, że interesujące jest to, że możesz przejść tylko 3 poziomy zagnieżdżania, a teraz, gdy wiem, mogę to obejść. – sholmes
Tak, możesz zrobić to na odwrót używając 'whereHas'. To dobry sposób, zależy tylko od twoich potrzeb. W każdym razie nie rozumiem co masz na myśli przez 3 poziomy zagnieżdżania? –