如何合并两个雄辩的收藏?

时间:2015-05-29 06:25:24

标签: php laravel eloquent laravel-collection

我有一个问题表和一个标签表。我想从给定问题的标签中获取所有问题。所以,例如,我可能有标签" Travel," "列车"和#34;文化"附在给定问题上。我希望能够获取这三个标签的所有问题。看起来棘手的是,问题和标签的关系是Eloquent中定义为manyToMany的多对多关系。

我考虑过尝试合并问题集合,如下所示:

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

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

6 个答案:

答案 0 :(得分:87)

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

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

答案 1 :(得分:18)

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

答案 2 :(得分:7)

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

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

答案 3 :(得分:1)

将两个不同的雄辩集合合并为一个,一些对象恰好具有相同的id,一个将覆盖另一个。请改用push()方法或重新考虑解决问题的方法以避免这种情况。 Refer to web

答案 4 :(得分:1)

为每个雄辩的收藏创建一个新的基本收藏,合并对我有用。

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

在这种情况下,不要通过主键进行限制。

答案 5 :(得分:0)

所有这些都不适用于我雄辩的收藏,laravel雄辩的收藏品使用项目我认为中的键导致合并问题,你需要获得第一个收藏作为一个数组返回,将其放入一个新的集合,然后将其他人推入新的集合中;

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