2015-05-29 10 views
17

Ich habe eine Fragetabelle und eine Tag-Tabelle. Ich möchte alle Fragen von den Umbauten einer gegebenen Fragen holen. So kann ich zum Beispiel die Tags "Reisen", "Züge" und "Kultur" an eine gegebene Frage angehängt haben. Ich möchte alle Fragen für diese drei Tags abrufen können. Das Schwierige, so scheint es, ist, dass die Beziehung zwischen Fragen und Tags ein Viele-zu-Viele ist, das in Eloquent definiert ist, wie es zu vielen gehört.Wie zwei eloquente Sammlungen zusammenführen?

Ich dachte daran, zu versuchen, die Fragen Kollektionen wie unten zu fusionieren:

foreach ($question->tags as $tag) { 
    if (!isset($related)) { 
     $related = $tag->questions; 
    } else { 
     $related->merge($tag->questions); 
    } 
} 

Es ist nicht zu funktionieren scheint aber. Scheint nichts zu verschmelzen. Versuche ich das richtig? Gibt es vielleicht auch einen besseren Weg, Zeilen in einer Viele-zu-Viele-Beziehung in Eloquent zu holen?

+0

Haben Sie die Dokumentation über eifrig Laden und das mit Methode? Ihr Problem könnte mit einer besseren eloquenten Abfrage leicht gelöst werden. Sobald ich hinter einen Computer komme, schreibe ich ein Beispiel, es sei denn jemand schlägt mich dazu. – Luceos

+1

@ Luceos 'mit' wird nicht helfen. Es ist 'whereHas', das benötigt wird - wie in der Antwort unten. –

+0

ja, mein Fehler; Sie sind korrekt – Luceos

Antwort

8

Die merge()-Methode auf der Collection ändert nicht die Auflistung, auf der es aufgerufen wurde. Es gibt eine neue Sammlung mit den neuen Daten fusionieren Sie müßten.

$related = $related->merge($tag->questions); 

Aber ich denke, ich ist das Problem von dem falschen Winkel Angriff zu nehmen.

Da Sie nach Fragen suchen, die bestimmte Kriterien erfüllen, wäre es wahrscheinlich einfacher, auf diese Weise nachzufragen. Die has() und whereHas() Methoden werden verwendet, um eine Abfrage basierend auf dem Vorhandensein eines verwandten Datensatzes zu generieren.

Wenn Sie nur nach Fragen mit einem beliebigen Tag suchen, verwenden Sie die Methode has(). Da Sie nach Fragen mit einem bestimmten Tag suchen, verwenden Sie die whereHas(), um die Bedingung hinzuzufügen.

Also, wenn Sie alle Fragen möchten, die entweder mit ‚Travel‘ mindestens ein Tag haben, ‚Züge‘ oder ‚Kultur‘, würde Ihre Abfrage wie folgt aussehen:

$questions = Question::whereHas('tags', function($q) { 
    $q->whereIn('name', ['Travel', 'Trains', 'Culture']); 
})->get(); 

Wenn Sie alle wollten Fragen, die alle drei dieser Tags hätte, würde Ihre Frage wie folgt aussehen:

$questions = Question::whereHas('tags', function($q) { 
    $q->where('name', 'Travel'); 
})->whereHas('tags', function($q) { 
    $q->where('name', 'Trains'); 
})->whereHas('tags', function($q) { 
    $q->where('name', 'Culture'); 
})->get(); 
+0

+, aber die zweite (alle Tags) Option, die Sie vorgeschlagen haben, könnte vereinfacht werden: http://StackOverflow.com/a/24706347/784588 –

+0

, aber Sie können die Tag-Namen nicht fest codieren.In diesem Beispiel ist die Frage, diese Tags zu haben, aber in anderen Fragen werden die Tags variieren –

45

die merge Methode, um die fusionierten Auflistung zurückgibt, ist es nicht die ursprüngliche Sammlung mutieren, so müssen Sie die folgende

01 tun

Anwendung des Beispiel, um Ihren Code

$related = new Collection(); 

foreach ($question->tags as $tag) 
{ 
    $related = $related->merge($tag->questions); 
} 
+0

Ich habe versucht, eine flache Liste von einem Baum zu bauen, mit Push war was ich brauchte, aber die foreach Ansatz wirklich geholfen. – George

0

Zusammenführen von zwei verschiedenen eloquent Sammlungen in ein und einige Objekte passieren die gleiche ID haben, wird eine die andere überschreiben. Verwenden Sie stattdessen die Methode push(), oder überdenken Sie Ihren Ansatz für das Problem, um dies zu vermeiden. Refer to web

-1
$users = User::all(); 
$associates = Associate::all(); 

$userAndAssociate = $users->merge($associates);