Как объединить две красноречивые коллекции?
У меня есть таблица вопросов и таблица тегов. Я хочу получить все вопросы из тегов данного вопроса. Так, например, к данному вопросу могут быть прикреплены теги "Поездка", "Поезда" и "Культура". Я хочу быть в состоянии получить все вопросы для этих трех тегов. Хитрость, как кажется, заключается в том, что вопросы и теги имеют отношение "многие ко многим", которое в 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;
}