Laravel: Abfragen und den Zugriff auf untergeordnete Objekte in verschachtelten Beziehung mit where-Klauseln
Ich versuche, um Zugriff auf die untergeordneten Objekte in den verschachtelten Beziehungen, die viele Ergebnisse aus dem Eltern-Objekt.
Sagen wir mal ich habe 4 Modelle : Land - Provinzen - Städte - Gemeinden
Ihre Beziehungen sind wie folgt :
Land Modell
class Country extends Eloquent
{
protected $table = 'countries';
public function provinces()
{
return $this->hasMany('Province');
}
}
Provinz Modell
class Province extends Eloquent
{
protected $table = 'provinces';
public function cities()
{
return $this->hasMany('City');
}
public function country()
{
return $this->belongsTo('Country');
}
}
Stadt-Modell
class City extends Eloquent
{
protected $table = 'cities';
public function municipalities()
{
return $this->hasMany('Municipality');
}
public function province()
{
return $this->belongsTo('Province');
}
}
Gemeinde Modell
class Municipality extends Eloquent
{
protected $table = 'municipalities';
public function cities()
{
return $this->belongsTo('City');
}
}
Nun, was ich versuche zu tun ist, erhalten alle Gemeinden in einem bestimmten Land, das eine Bevölkerung von über 9000 und befinden sich in Provinzen, die als West.
Bisher habe ich so etwas wie dieses :
$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);
Kann ich jetzt einfach die Provinzen mit $country->provinces
aber ich kann nicht noch tiefer als das.
EDIT1 : Befestigung der belongsTo-Beziehung, wie bemerkt, durch Jarek.
EDIT2: zusätzlich zu Jarek die Antwort, die ich wollte zu teilen, was ich auch gefunden, aber Jarek ist wahrscheinlich die richtige Methode.
Anstatt zu versuchen, um zu gehen von oben nach unten (Land -> Gemeinde), habe ich beschlossen, zu versuchen, den anderen Weg (Gemeinde -> Land) Hier ist, wie es funktioniert (und ich es getestet habe, funktioniert auch)
$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();
Ich habe keine Ahnung, ob dies eine tatsächliche richtige Weg, oder wenn die Leistung akzeptiert werden würde, aber es schien, den trick zu tun für mich jedoch Jarek die Antwort sieht eher elegant.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre
Municipality
-City
ist wahrscheinlichbelongsTo
, nichthasMany
wie in der paste.Sowieso können Sie
hasManyThrough
Bezug auf den Zugang weit damit verbundene Sammlung:Leider gibt es keinen Bezug für 3-Ebene verschachteln, d.h. Sie können nicht dies tun nur so.
Nächsten, Ihren code mit
whereHas
keine Grenzeprovinces
zuwest
undmunicipalities
zu9000+
, aber nur begrenztcountries
zu denen, die mit Ihnen verwandt sind. In Ihrem Fall bedeutet dies, dass Ergebnis entwederCountry
(wenn seine Beziehungen entsprechen diesen Anforderungen) odernull
sonst.Also, wenn Sie wirklich wollen, zu begrenzen, Verwandte Sammlungen, dann müssen Sie dieses Stück:
Diese Anwendung ist eager loading constraints, und was es tut ist:
Da Sie nicht daran interessiert, die Städte, die Sie nutzen könnten
hasManyThrough
auf die Provinz:dann:
Jedoch in beiden Fällen können Sie nicht auf die Kommunen direkt, aber nur so:
That being said, wenn Sie möchten, um zu arbeiten mit alle jene Gemeinden, müssen Sie diesen trick:
Dieser wird ausgeführt, zusätzliche Abfrage, nun aber die Gemeinden sind in Einzel -, flach-Sammlung, so ist es sehr einfach, mit zu arbeiten. Sonst werden Sie wahrscheinlich am Ende mit einem Bündel von foreach-Schleifen.
whereHas
. Dies ist ein guter Weg, nur hängt von Ihren Bedürfnissen ab. Trotzdem verstehe ich nicht was du meinst mit 3 Ebenen verschachteln?