Laravel 10中whereHas过滤数据无效问题求助
问题分析与解决:whereHas过滤后关联数据仍全量显示
你遇到的问题核心是对whereHas和with的作用边界理解有误:
whereHas的作用是筛选出拥有符合条件关联数据的主模型(OutboundRequest),它只会限制主模型的查询结果,不会对预加载的关联数据本身做过滤。with('outboundmaterialrequest')是直接预加载主模型关联的所有outboundmaterialrequest数据,完全不受whereHas的过滤逻辑影响,所以哪怕主模型被筛选出来了,关联数据还是会全量显示。
解决方法
要同时实现「筛选主模型」+「只加载符合条件的关联数据」,需要把关联过滤逻辑同时写到with的闭包里,和whereHas配合使用:
$listreq2 = OutboundRequest::with(['outboundmaterialrequest' => function ($query) use ($ids) { // 这里过滤预加载的关联数据 $query->whereIn('id', $ids); }]) ->whereIn('id', $outboundIds) ->whereHas('outboundmaterialrequest', function ($query) use ($ids) { // 这里筛选拥有符合条件关联的主模型 $query->whereIn('id', $ids); })->get();
如果你的Laravel版本在8.40及以上,还可以用whereRelation简化whereHas的写法:
$listreq2 = OutboundRequest::with(['outboundmaterialrequest' => function ($query) use ($ids) { $query->whereIn('id', $ids); }]) ->whereIn('id', $outboundIds) ->whereRelation('outboundmaterialrequest', 'id', 'in', $ids) ->get();
额外提醒
如果只写with的闭包过滤而不加whereHas,主模型会被全量查询出来——那些没有符合条件关联数据的主模型,其outboundmaterialrequest字段会是一个空集合,这可能不是你想要的结果。
内容的提问来源于stack exchange,提问作者Muttaqin
相关产品推荐
相关产品推荐

