Laravel多层关联查询下筛选仅包含指定id Todo的Milestone
首先你给出的Milestone模型关联存在笔误,按照你的查询逻辑,Milestone应该是关联Todo模型而非自关联,对应关联方法应为:
public function todo() { return $this->hasMany('App\Models\Todo'); }
问题原因
你当前的写法仅对milestones下的todo关联做了过滤,没有对milestones本身做筛选,所以会返回符合条件的项目下的所有里程碑,仅不符合要求的里程碑的todo字段为空。
修复后的查询代码
你需要在预加载milestones关联时就添加过滤条件,同时移除代码中未使用的$UserId变量:
$query = Project::whereHas('milestones', function($query) { $query->whereHas('todo', function ($query) { $query->where('id', 3); }); })->with([ 'milestones' => function($query) { $query->whereHas('todo', function ($query) { $query->where('id', 3); })->with('todo', function($query) { $query->where('id', 3); }); } ])->get();
Laravel 9+ 简化写法
如果你使用Laravel 9及以上版本,可以使用withWhereHas方法同时完成关联存在校验和预加载过滤,代码更简洁:
$query = Project::whereHas('milestones.todo', fn($q) => $q->where('id', 3)) ->with([ 'milestones' => fn($q) => $q->withWhereHas('todo', fn($q) => $q->where('id', 3)) ]) ->get();
内容的提问来源于stack exchange,提问作者SaschaK
相关产品推荐
相关产品推荐

