2016-07-31 26 views
0

In den Laravel-Dokumenten diskutieren sie eifrig ladende Daten, um das N + 1-Abfrageproblem zu lösen. Ich möchte meine Daten basierend auf den Daten aus diesen Beziehungen filtern, ohne die Ergebnisse durchlaufen zu müssen (das würde ich gerne zur Abfragezeit machen).Filtern von Modellen durch eifrig geladene Daten, auf der Datenbankebene

Ein Beispiel in der Dokumentation ist wie folgt:

Wenn ich diese Bücher filtern wollte, um nur diejenigen einzuschließen, deren Autor in der Postleitzahl 12345 lebt, wie würde ich das tun?

Weder die folgenden Abfragen arbeiten für mich:

$books = App\Book::with('author.contacts')->where('zip', 12345)->get(); 
$books = App\Book::with('author.contacts')->where('author.contacts.zip', 12345)->get(); 

Gibt es eine einfache Möglichkeit, dies in Eloquent zu tun?

+0

Sie sollten in der Lage sein, etwas wie dieses zu tun 'App \ Book :: mit (' author.contacts '=> Funktion ($ q) {$ q-> wo (' zip ', 12345)}) -> bekommen(); ' – Andrew

+0

@Andrew Das ändert eigentlich nicht die Anzahl der Bücher, die ich in der Sammlung überhaupt bekomme. Wenn ich 'toSql' verwende, um die Abfrage zu dumpen, lande ich mit' "Select * from books" ', was nahelegt, dass nur gefiltert wird, welche Relationen eifrig geladen werden, nicht die Bücher in der Abfrage filtern, die ich möchte. – Wilduck

+0

Okay, mein schlechtes dann. Ich habe tatsächlich diese Abfrage auf meinem lokalen Rechner versucht, sollte es gut funktionieren 'App \ Book :: mit ('author.contacts') -> whereHas ('author.contacts' => Funktion ($ q) {$ q -> wo ('zip', 12345)}) -> get(); '. Ich werde meinen Hut essen, wenn das nicht richtig funktioniert. Siehe auch [this] (http://stackoverflow.com/questions/28321928/laravel-eloquent-orm-filtering-with-relationship) als Referenz. – Andrew

Antwort

1

Um zu erreichen, was Sie suchen Sie die folgende Abfrage verwenden:

App\Book::with('author.contacts') 
->whereHas('author.contacts' => function($q){ 
    $q->where('zip', 12345)} 
) 
->get(); 

Diskutierbar könnten Sie auch eine ähnliche Abfrage im contacts Modell, etwas entlang der Linien von verwenden:

public function withZipCode() 
{ 
    return Contacts::where('zip', 12345); 
} 

Ich habe es ehrlich gesagt nicht versucht, aber es sollte funktionieren.