查找在拉拉维尔的口才上以多对多关系共享标签的文章的正确方法



我有三个表,一个文章表,一个标签表,还有一个叫做article_tags的中间数据透视表,它只包含一个article_id和tag_id,形成多对多关系。

我想编写一个接收文章的函数,并返回一个集合或查询,其中包含与收到的文章共享至少一个标签的所有文章,在尝试了一堆不同的解决方案后,我有这个:

public function scopeRelated($query, Article $article)
{
return $query->whereHas('tags', function ($query) use ($article) {
// I've tried a bunch of different lines, like just $article->tags
$query->whereIn('tags', $article->tags->pluck('id'));
});
}

这将返回一个错误:

Illuminate/Database/QueryException 与消息 'SQLSTATE[42S22]: 找不到列:1054 "where 子句"中的未知列"标记"(SQL: 从存在articles中选择 *(从内部联接中选择 *tagsarticle_tagtags.id=article_tag.tag_idarticles.id=article_tag.article_idtags(1, 6, 4)))'

显然,Eloquent 正在尝试将标签与 Articles 表上的"标签"列匹配,该列不存在。 问我想要什么的正确方法是什么?

使用tag_id对子查询具有超特定性:

return $query->whereHas('tags', function ($query) use ($article) {
$query->whereIn('tag_id', $article->tags->pluck('id'));
});

另一个答案中建议'id'在 Laravel 5.8 和 MySQL 5.7 中对我有用。也许启用了某种严格模式,或者当您不需要它时,您的article_tag表中确实有一个id列。

另外,不要忘记从相关结果中排除原始文章! :)

$query
->whereHas('tags', function ($query) use ($article) {
$query->whereIn('tag_id', $article->tags->pluck('id'));
})
->where('id', '<>', $article->id);

'tags'列替换为'tags.id'。此外,如果$article对象没有已经加载标签关系,我建议$article->tags()->pluck('id')因为这种方式 eloquent 只会查询文章 ID。

阿肯·罗伯茨是对的,你可能想从结果中排除$article。我假设包含文章的表称为articles.

因此,查询将如下所示:

return $query->whereHas('tags', function ($query) use ($article) {
$query->whereIn('tags.id', $article->tags()->pluck('id'));
})->where('articles.id', '<>', $article->id);

最新更新