我有一个问题表和一个标签表。我想从给定问题的标签中获取所有问题。例如,我可能会给给定的问题加上"旅行"、"火车"answers"文化"标签。我希望能够获取这三个标签的所有问题。问题在于,问题和标签的关系是一个多对多的关系,在Eloquent中定义为belongsToMany。
我想尝试合并问题集合如下:
foreach ($question->tags as $tag) {
if (!isset($related)) {
$related = $tag->questions;
} else {
$related->merge($tag->questions);
}
}
它似乎不起作用。似乎没有合并任何东西。我这样做对吗?此外,是否有更好的方法在Eloquent中获取多对多关系中的一行?
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);
}
Collection
上的merge()
方法不修改调用它的集合。它返回一个合并了新数据的新集合。您需要:
$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();
$users = User::all();
$associates = Associate::all();
$userAndAssociate = $users->merge($associates);
将两个不同的雄辩集合合并为一个,并且某些对象碰巧具有相同的id,其中一个将覆盖另一个。使用push()方法代替,或者重新考虑解决问题的方法以避免这种情况。参考网页
为每个雄辩的集合创建一个新的基本集合。
$foo = collect(Foo::all());
$bar = collect(Bar::all());
$merged = $foo->merge($bar);
我在使用merge时遇到了一些问题。所以我使用concat。你可以像下面这样使用它。
$users = User::all();
$associates = Associate::all();
$userAndAssociate = $users->concat($associates);
在雄辩的集合上都不适合我,laravel雄辩的集合使用项目中的键,我认为这会导致合并问题,您需要将第一个集合作为数组返回,将其放入新集合中,然后将其他集合推入新集合;
public function getFixturesAttribute()
{
$fixtures = collect( $this->homeFixtures->all() );
$this->awayFixtures->each( function( $fixture ) use ( $fixtures ) {
$fixtures->push( $fixture );
});
return $fixtures;
}
我想补充一点,我发现concat方法似乎不会基于ID覆盖,而合并方法则会。Concat似乎为我工作,而合并引起的问题。
我很抱歉,但是从PHP 7.4开始,你可以这样做(最好使用merge
)。
$foo = Foo::all();
$bar = Bar::all();
/** $foo will contain $foo + $bar */
$foo->push(...$bar);