Ich habe eine Fragentabelle und eine Tags-Tabelle. Ich möchte alle Fragen von Tags einer bestimmten Frage abrufen. So kann ich beispielsweise die Tags "Reisen", "Züge" und "Kultur" an eine bestimmte Frage anhängen. Ich möchte in der Lage sein, alle Fragen für diese drei Tags abzurufen. Das Knifflige, so scheint es, ist, dass die Beziehung zwischen Fragen und Tags ein Viele-zu-Viele-Verhältnis ist, das in Eloquent als zu ToMany gehörend definiert wird.
Ich habe darüber nachgedacht, die Fragen Sammlungen wie folgt zusammenzuführen:
foreach ($question->tags as $tag) {
if (!isset($related)) {
$related = $tag->questions;
} else {
$related->merge($tag->questions);
}
}
Es scheint jedoch nicht zu funktionieren. Scheint nichts zu verschmelzen. Versuche ich das richtig? Gibt es in Eloquent vielleicht auch eine bessere Möglichkeit, eine Reihe von Zeilen in einer Viele-zu-Viele-Beziehung abzurufen?
quelle
with
wird nicht helfen. Es ist daswhereHas
, was benötigt wird - wie in der Antwort unten.Antworten:
Die Merge-Methode gibt die zusammengeführte Sammlung zurück. Sie mutiert nicht die ursprüngliche Sammlung. Daher müssen Sie die folgenden Schritte ausführen
$original = new Collection(['foo']); $latest = new Collection(['bar']); $merged = $original->merge($latest); // Contains foo and bar.
Anwenden des Beispiels auf Ihren Code
$related = new Collection(); foreach ($question->tags as $tag) { $related = $related->merge($tag->questions); }
quelle
getKey
um merge Ergebnisse, soModel::all()->merge(Model::all())->count() === Model::all()->count()
Die
merge()
Methode auf demCollection
ändert nicht die Sammlung, für die sie aufgerufen wurde. Es wird eine neue Sammlung mit den neu zusammengeführten Daten zurückgegeben. Sie benötigen:Ich denke jedoch, dass Sie das Problem aus dem falschen Blickwinkel angehen.
Da Sie nach Fragen suchen, die bestimmte Kriterien erfüllen, ist es wahrscheinlich einfacher, diese auf diese Weise abzufragen. Die Methoden
has()
undwhereHas()
werden verwendet, um eine Abfrage basierend auf dem Vorhandensein eines zugehörigen Datensatzes zu generieren.Wenn Sie nur nach Fragen suchen, die ein Tag haben, würden Sie die
has()
Methode verwenden. Da Sie nach Fragen mit einem bestimmten Tag suchen, würden Sie das verwendenwhereHas()
, um die Bedingung hinzuzufügen.Wenn Sie also alle Fragen haben möchten, die mindestens ein Tag mit "Reisen", "Züge" oder "Kultur" haben, sieht Ihre Anfrage folgendermaßen aus:
$questions = Question::whereHas('tags', function($q) { $q->whereIn('name', ['Travel', 'Trains', 'Culture']); })->get();
Wenn Sie alle Fragen mit allen drei Tags haben möchten, sieht Ihre Anfrage folgendermaßen aus:
$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();
quelle
quelle
Füge zwei verschiedene eloquente Sammlungen zu einer zusammen und einige Objekte haben zufällig dieselbe ID, eines überschreibt das andere. Verwenden Sie stattdessen die push () -Methode oder überdenken Sie Ihre Herangehensweise an das Problem, um dies zu vermeiden. Siehe Web
quelle
Bei eloquenten Sammlungen funktionieren nicht alle für mich. Bei eloquenten Sammlungen von Laravel wird der Schlüssel aus den Elementen verwendet, die meiner Meinung nach zu Zusammenführungsproblemen führen. Sie müssen die erste Sammlung als Array zurückerhalten, diese in eine neue Sammlung einfügen und dann die anderen in die Sammlung verschieben die neue Kollektion;
public function getFixturesAttribute() { $fixtures = collect( $this->homeFixtures->all() ); $this->awayFixtures->each( function( $fixture ) use ( $fixtures ) { $fixtures->push( $fixture ); }); return $fixtures; }
quelle
Beim Erstellen einer neuen Basissammlung für jede beredte Sammlung funktioniert die Zusammenführung für mich.
In diesem Fall haben keine Konflikte mit den Primärschlüsseln.
quelle