Как объединить две красноречивые коллекции?

У меня есть таблица вопросов и таблица тегов. Я хочу получить все вопросы из тегов данного вопроса. Так, например, к данному вопросу могут быть прикреплены теги "Поездка", "Поезда" и "Культура". Я хочу быть в состоянии получить все вопросы для этих трех тегов. Хитрость, как кажется, заключается в том, что вопросы и теги имеют отношение "многие ко многим", которое в Eloquent определено как ownToMany.

Я думал о попытке объединить Коллекции вопросов, как показано ниже:

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

Похоже, это не работает. Кажется, ничего не сливается. Я пытаюсь это правильно? Кроме того, возможно, в Eloquent есть лучший способ получить ряд строк в отношении "многие ко многим"?

Ответы

Ответ 1

Метод слияния возвращает объединенную коллекцию, она не мутирует исходную коллекцию, поэтому вам нужно сделать следующее

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

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

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

Применение примера к вашему коду

$related = new Collection();

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

Ответ 2

Метод merge() в Collection не изменяет коллекцию, на которую он был вызван. Он возвращает новую коллекцию с объединенными новыми данными. Вам понадобится:

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

Однако, я думаю, вы решаете проблему с неправильным углом.

Поскольку вы ищете вопросы, которые отвечают определенным критериям, вероятно, было бы проще запросить таким образом. Методы has() и whereHas() используются для генерации запроса на основе существования связанной записи.

Если вы просто искали вопросы с любым тегом, вы должны использовать метод has(). Поскольку вы ищете вопросы с определенным тегом, вы должны использовать whereHas() для добавления условия.

Итак, если вы хотите, чтобы все вопросы, имеющие хотя бы один тег либо с помощью "Путешествия", "Поезда", либо "Культура", ваш запрос выглядел бы так:

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

Если вам нужны все вопросы, содержащие все три тега, ваш запрос будет выглядеть так:

$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();

Ответ 3

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

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

Ответ 4

Объедините две разные красноречивые коллекции в одну, а некоторые объекты имеют один и тот же идентификатор, один перепишет другой. Используйте метод push() или переосмыслите свой подход к проблеме, чтобы этого избежать. Обратитесь к веб-сайту

Ответ 5

Все они не работают для меня в красноречивых коллекциях, в красноречивых коллекциях laravel используется ключ от элементов, которые, как мне кажется, вызывают проблемы слияния, вам нужно вернуть первую коллекцию в виде массива, поместить ее в новую коллекцию, а затем поместить остальные в новая коллекция;

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