php 如何合并两个 Eloquent 集合?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30522528/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 21:50:56  来源:igfitidea点击:

How to Merge Two Eloquent Collections?

phplaraveleloquentlaravel-collection

提问by Martyn

I have a questions table and a tags table. I want to fetch all questions from tags of a given question. So, for example, I may have the tags "Travel," "Trains" and "Culture" attached to a given question. I want to be able to fetch all questions for those three tags. The tricky, so it seems, is that questions and tags relationship is a many-to-many defined in Eloquent as belongsToMany.

我有一个问题表和一个标签表。我想从给定问题的标签中获取所有问题。因此,例如,我可能将标签“旅行”、“火车”和“文化”附加到给定的问题。我希望能够获取这三个标签的所有问题。棘手的是,问题和标签的关系在 Eloquent 中是多对多的,定义为belongsToMany。

I thought about trying to merge the questions Collections as below:

我想尝试合并问题集合如下:

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

It doesn't seem to work though. Doesn't seem to merge anything. Am I attempting this correctly? Also, is there perhaps a better way to fetch a row of rows in a many-to-many relationship in Eloquent?

虽然它似乎不起作用。似乎没有合并任何东西。我是否正确尝试?另外,是否有更好的方法在 Eloquent 中以多对多关系获取一行行?

回答by Wader

The merge method returns the merged collection, it doesn't mutate the original collection, thus you need to do the following

merge 方法返回合并后的集合,它不会改变原始集合,因此您需要执行以下操作

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

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

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

Applying the example to your code

将示例应用于您的代码

$related = new Collection();

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

回答by patricus

The merge()method on the Collectiondoes not modify the collection on which it was called. It returns a new collection with the new data merged in. You would need:

上的merge()方法Collection不会修改调用它的集合。它返回一个合并了新数据的新集合。您需要:

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

However, I think you're tackling the problem from the wrong angle.

但是,我认为您从错误的角度解决问题。

Since you're looking for questions that meet a certain criteria, it would probably be easier to query in that manner. The has()and whereHas()methods are used to generate a query based on the existence of a related record.

由于您正在寻找满足特定条件的问题,因此以这种方式进行查询可能会更容易。该has()whereHas()方法用于基于相关记录是否存在的查询。

If you were just looking for questions that have any tag, you would use the has()method. Since you're looking for questions with a specific tag, you would use the whereHas()to add the condition.

如果您只是在寻找带有任何标签的问题,则可以使用该has()方法。由于您正在寻找带有特定标签的问题,因此您可以使用whereHas()来添加条件。

So, if you want all the questions that have at least one tag with either 'Travel', 'Trains', or 'Culture', your query would look like:

因此,如果您想要所有问题至少有一个带有“旅行”、“火车”或“文化”的标签,您的查询将如下所示:

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

If you wanted all questions that had all three of those tags, your query would look like:

如果您想要所有具有这三个标签的所有问题,您的查询将如下所示:

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

回答by sh6210

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

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

回答by newbie2005

Merge two different eloquent collections into one and some objects happen to have the same id, one will overwrite the other. Use push() method instead or rethink your approach to the problem to avoid that. Refer to web

将两个不同的 eloquent 集合合并为一个,并且某些对象碰巧具有相同的 id,一个会覆盖另一个。改用 push() 方法或重新考虑解决问题的方法以避免这种情况。 参考网页

回答by Luke Snowden

All do not work for me on eloquent collections, laravel eloquent collections use the key from the items I thinkwhich causes merging issues, you need to get the first collection back as an array, put that into a fresh collection and then push the others into the new collection;

所有在eloquent 集合上都对我不起作用,laravel eloquent 集合使用我认为会导致合并问题的项目中的键,您需要将第一个集合作为数组取回,将其放入一个新集合中,然后将其他集合推入新系列;

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

回答by Pooria Honarmand

In order to combine two eloquent collections we can use union.
Here is official docs: https://laravel.com/docs/5.8/queries#unions.

For example: (imagine we have two users)

为了结合两个雄辩的集合,我们可以使用union.
这是官方文档:https: //laravel.com/docs/5.8/queries#unions

例如:(假设我们有两个用户)

$posts1 = $user1->posts();
$posts2 = $user2->posts();

$combined = $posts1->union($posts2)->get();
// returns posts belong to two users.

回答by Jo?o Carlos Junior

Creating a new base collection for each eloquent collection the merge works for me.

为每个雄辩的集合创建一个新的基础集合,合并对我有用。

$foo = collect(Foo::all());
$bar = collect(Bar::all());
$merged = $foo->merge($bar);

In this case don't have conflits by its primary keys.

在这种情况下,它的主键没有冲突。