Laravel 5.6 Eloquent多表查询:筛选指定tag的issue
解决Laravel 5.6 Eloquent查询关联中间表的问题
我来帮你排查下这个问题!你当前的查询返回所有issue的原因很明确——join条件写错了,你现在是把issues_tags表自己的project_id和issue_id做关联,完全没和issues表建立正确的关联关系,相当于没加过滤,自然会返回全量数据。
错误原因分析
你原来的代码:
$issues = Issue::join('issues_tags', 'issues_tags.project_id', 'issues_tags.issue_id')->where('issues_tags.tag_id', 5)->select('issues.*')->get();
这里的join第二个和第三个参数是关联字段,但你写的都是issues_tags表的字段,没有关联到issues表的对应字段,这就导致关联逻辑完全失效。
正确的解决方案
根据你的表结构,关联条件应该是:
issues.project_id=issues_tags.project_idissues.id=issues_tags.issue_id
方案1:使用原生Join(闭包写法更清晰)
$issues = Issue::join('issues_tags', function ($join) { // 同时关联两个复合条件 $join->on('issues.project_id', '=', 'issues_tags.project_id') ->on('issues.id', '=', 'issues_tags.issue_id'); })->where('issues_tags.tag_id', 5) ->select('issues.*') ->distinct() // 可选:如果有重复数据可以加上去重 ->get();
方案2:使用Eloquent关联(更符合Laravel风格)
首先在Issue模型中定义与Tag的关联(因为是多对多,中间表是issues_tags,且需要匹配project_id):
// app/Issue.php public function tags() { return $this->belongsToMany(Tag::class, 'issues_tags', 'issue_id', 'tag_id') ->withPivot('project_id') ->wherePivot('project_id', $this->project_id); }
然后用whereHas来筛选关联了指定tag的issue:
$issues = Issue::whereHas('tags', function ($query) { $query->where('tag_id', 5); })->get();
这种方式更贴合Laravel的ORM设计,代码可读性更高,也更容易维护。
内容的提问来源于stack exchange,提问作者dom_ahdigital
相关产品推荐
相关产品推荐

