web-dev-qa-db-fra.com

Comment fusionner deux collections éloquentes?

J'ai un tableau de questions et un tableau de balises. Je veux extraire toutes les questions des balises d'une question donnée. Ainsi, par exemple, les étiquettes "Voyage", "Trains" et "Culture" peuvent être associées à une question donnée. Je veux pouvoir aller chercher toutes les questions pour ces trois balises. Le problème, semble-t-il, est que la relation entre les questions et les balises est définie dans Eloquent par plusieurs comme une appartenance à bien.

J'ai pensé à essayer de fusionner les questions Collections comme ci-dessous:

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

Cela ne semble pas fonctionner cependant. Ne semble pas fusionner quoi que ce soit. Est-ce que je tente ceci correctement? En outre, existe-t-il peut-être un meilleur moyen d'extraire une ligne de lignes dans une relation plusieurs à plusieurs dans Eloquent?

40
Martyn

La méthode de fusion renvoie la collection fusionnée, elle ne modifie pas la collection d'origine, vous devez donc procéder comme suit

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

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

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

Appliquer l'exemple à votre code

$related = new Collection();

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

La méthode merge() sur la Collection ne modifie pas la collection sur laquelle elle a été appelée. Il retourne une nouvelle collection avec les nouvelles données fusionnées. Vous aurez besoin de:

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

Cependant, je pense que vous abordez le problème sous le mauvais angle.

Puisque vous recherchez des questions qui répondent à certains critères, il serait probablement plus facile d'interroger de cette manière. Les méthodes has() et whereHas() sont utilisées pour générer une requête basée sur l'existence d'un enregistrement associé.

Si vous ne recherchiez que des questions comportant un tag, utilisez la méthode has(). Puisque vous recherchez des questions avec une balise spécifique, vous utiliseriez la fonction whereHas() pour ajouter la condition.

Ainsi, si vous souhaitez que toutes les questions comportant au moins un tag avec "Travel", "Trains" ou "Culture", votre requête ressemble à ceci:

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

Si vous voulez toutes les questions qui ont ces trois balises, votre requête ressemblera à ceci:

$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

Fusionnez deux collections éloquentes différentes en une seule et certains objets ont le même identifiant, l’une écrasant l’autre. Utilisez plutôt la méthode Push () ou repensez votre approche du problème pour éviter cela . Voir web

0
newbie2005

Tous ne fonctionnent pas pour moi sur collections éloquentes , Laravel collections éloquentes utilisent la clé des éléments je pense ce qui cause des problèmes collection fraîche et puis poussez les autres dans la nouvelle collection;

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