Laravel多对多关联查询:仅返回满足pivot条件的Post数据
解决多对多关联中仅查询符合中间表条件的Post数据
你当前的代码用with()过滤关联的employees数据,但这只会限制加载的关联内容,不会筛选Post本身——所以即使某个Post没有符合条件的employees关联(比如employees数组为空),它还是会被返回。
要只保留中间表满足user_id为当前登录用户且status为Accepted的Post,需要用whereHas()来做存在性约束,确保Post存在符合条件的关联记录,同时配合with()加载过滤后的关联数据,避免N+1查询。
修改后的代码如下:
public function accepted() { $posts = Post::whereHas('employees', function ($q) { $q->wherePivot('status', 'Accepted') ->where('user_id', Auth::id()); }) ->with(['employees' => function ($q) { $q->wherePivot('status', 'Accepted') ->where('user_id', Auth::id()); }]) ->with('address', 'service') ->orderBy('created_at', 'DESC') ->paginate(10); return response()->json($posts); }
关键说明:
whereHas('employees', ...):这一步会筛选出至少有一个符合条件的employees关联的Post,直接排除掉没有符合条件关联的Post。- 保留
with(['employees' => ...]):确保加载的employees数据是符合条件的,而不是该Post的所有employees记录。 - 如果你用的是Laravel 8+,可以用
withWhereHas()简化代码,它会自动把whereHas的条件应用到with的关联查询中,代码更简洁:
public function accepted() { $posts = Post::withWhereHas('employees', function ($q) { $q->wherePivot('status', 'Accepted') ->where('user_id', Auth::id()); }) ->with('address', 'service') ->orderBy('created_at', 'DESC') ->paginate(10); return response()->json($posts); }
这样就能得到仅符合中间表条件的Post数据,不会再返回employees数组为空的Post了。
内容的提问来源于stack exchange,提问作者Zia
相关产品推荐
相关产品推荐

