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

Mar*_*tyn 58 php laravel eloquent laravel-collection

我有一个问题表和一个标签表.我想从给定问题的标签中获取所有问题.因此,举例来说,我可能会在给定问题上附加标签"旅行","火车"和"文化".我希望能够获取这三个标签的所有问题.看起来棘手的是,问题和标签关系是Eloquent中定义为manyToMany的多对多关系.

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

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

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

Wad*_*der 104

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

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

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

$merged = $original->merge($latest); // Contains foo and bar.
Run Code Online (Sandbox Code Playgroud)

将示例应用于您的代码

$related = new Collection();

foreach ($question->tags as $tag)
{
    $related = $related->merge($tag->questions);
}
Run Code Online (Sandbox Code Playgroud)


pat*_*cus 23

merge()方法Collection不会修改调用它的集合.它返回一个新集合,其中包含新数据.您需要:

$related = $related->merge($tag->questions);
Run Code Online (Sandbox Code Playgroud)

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

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

如果您只是在寻找有任何标签的问题,那么您将使用该has()方法.由于您正在查找具有特定标记的问题,因此您将使用whereHas()添加条件.

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

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

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

$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();
Run Code Online (Sandbox Code Playgroud)


sh6*_*210 11

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

$userAndAssociate = $users->merge($associates);
Run Code Online (Sandbox Code Playgroud)

  • 阅读此内容(覆盖):https://medium.com/@tadaspaplauskas/quick-tip-laravel-eloquent-collections-merge-gotcha-moment-e2a56fc95889 (4认同)
  • @Jeffz 仅根据 ID 合并“重复项”真的令人难以置信 (3认同)

小智 10

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

$foo = collect(Foo::all());
$bar = collect(Bar::all());
$merged = $foo->merge($bar);
Run Code Online (Sandbox Code Playgroud)

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


小智 8

将两个不同的雄辩的集合合并到一个中,并且某些对象碰巧具有相同的ID,一个将覆盖另一个。请改用push()方法或重新考虑解决问题的方法,以免发生这种情况。 参考网页

  • 谢谢,这让我看到了这里的评论https://medium.com/@jeffparr_57441/what-you-describe-happens-when-initial-eloquent-collection-in-your-case-cars-has-same-id -as-701e5a217372 似乎干净地完成了这项工作而无需覆盖。 (2认同)

Mir*_*ker 7

我在使用合并时遇到了一些问题。所以我使用了连接。你可以像下面这样使用它。

$users = User::all();
$associates = Associate::all();
$userAndAssociate = $users->concat($associates);
Run Code Online (Sandbox Code Playgroud)