wake-up-neo.com

Wie kann man zwei eloquente Sammlungen zusammenführen?

Ich habe eine Fragentabelle und eine Tags-Tabelle. Ich möchte alle Fragen aus den Tags einer bestimmten Frage abrufen. So kann ich beispielsweise die Tags "Reisen", "Züge" und "Kultur" an eine gegebene Frage anhängen. Ich möchte alle Fragen zu diesen drei Tags abrufen können. Das Kniffelige, so scheint es, ist, dass die Beziehung zwischen Fragen und Tags viele zu viele sind, die in Eloquent als "gehörtToMany" definiert sind.

Ich dachte über den Versuch nach, 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. Mache ich das richtig? Gibt es in Eloquent vielleicht auch eine bessere Möglichkeit, eine Reihe von Zeilen in einer Viele-zu-Viele-Beziehung abzurufen?

40
Martyn

Die Zusammenführungsmethode gibt die zusammengeführte Auflistung zurück, die ursprüngliche Auflistung wird jedoch nicht geändert. Daher müssen Sie Folgendes tun

$original = new Collection(['foo']);

$latest = new Collection(['bar']);

$merged = $original->merge($latest); // Contains foo and bar.

Das Beispiel auf Ihren Code anwenden

$related = new Collection();

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

Die merge()-Methode in der Collection ändert die Auflistung nicht, in der sie aufgerufen wurde. Es wird eine neue Sammlung mit den neuen Daten zurückgegeben. Sie benötigen:

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

Ich denke jedoch, dass Sie das Problem aus einem falschen Blickwinkel angehen.

Da Sie nach Fragen suchen, die bestimmte Kriterien erfüllen, ist es wahrscheinlich einfacher, auf diese Weise abzufragen. Die Methoden has() und whereHas() 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, verwenden Sie whereHas(), um die Bedingung hinzuzufügen.

Wenn Sie also alle Fragen haben möchten, die mindestens ein Tag mit "Reise", "Zug" oder "Kultur" haben, würde Ihre Abfrage folgendermaßen aussehen:

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

Wenn Sie alle Fragen mit allen drei dieser Tags haben möchten, würde Ihre Abfrage folgendermaßen 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();
16
patricus
$users = User::all();
$associates = Associate::all();

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

Fügen Sie zwei verschiedene eloquente Sammlungen in einer zusammen, und einige Objekte haben dieselbe ID, eines wird das andere überschreiben. Verwenden Sie stattdessen die Push () - Methode oder überdenken Sie Ihre Herangehensweise an das Problem, um dies zu vermeiden . Siehe web

0
newbie2005

Alle funktionieren nicht für eloquente Kollektionen , Laravel eloquent - Kollektionen verwenden den Schlüssel aus den Elementen ich denke was zu Problemen beim Zusammenführen führt, Sie müssen die erste Sammlung als Array zurückholen frische Sammlung und dann schieben Sie die anderen in die neue Sammlung;

public function getFixturesAttribute()
{
    $fixtures = collect( $this->homeFixtures->all() );
    $this->awayFixtures->each( function( $fixture ) use ( $fixtures ) {
        $fixtures->Push( $fixture );
    });
    return $fixtures;
}
0
Luke Snowden