如何合并两个雄辩的集合?

2022-08-30 07:10:01

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

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

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

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


答案 1

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

答案 2

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

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

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

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

如果您只是查找具有任何标记的问题,则可以使用该方法。由于您要查找具有特定标记的问题,因此可以使用 添加条件。has()whereHas()

因此,如果您希望所有问题都至少有一个带有“Travel”、“Trains”或“Culture”的标签,则您的查询将如下所示:

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

推荐