我有三个表,一个文章表,一个标签表,还有一个叫做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
中选择 *(从内部联接中选择 *tags
article_tag
tags
.id
=article_tag
.tag_id
articles
.id
=article_tag
.article_id
和tags
(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);