You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 02:25:09