Laravel whereDoesntHave失效求助:筛选无关联的物料数据
解决物料筛选中多余pivot关联的问题
我帮你分析下当前代码的问题,以及怎么修复:
问题出在哪?
whereDoesntHave的逻辑错误:你现在在whereDoesntHave里加了->where('Material_id', null),这完全偏离了需求——你要的是没有任何orders_material关联的物料,但这个条件是在找“关联存在但Material_id为空”的情况,逻辑完全反了。- 不必要的预加载关联:你用了
with(['orders_material','locals']),哪怕物料没有orders_material关联,这个预加载也会在JSON结果里生成一个空的orders_material字段,甚至如果有错误关联的话还会带出pivot内容。
修复步骤
方案一:直接修正查询逻辑(推荐)
去掉错误的where条件,同时移除不必要的orders_material预加载,代码改成这样:
$material = Material::with(['locals']) ->whereDoesntHave('orders_material') ->where('Categoria_id', $idcategory) ->where('SubCategoria_id', $idsubcategory) ->where('requisitado', '0') ->where('estado', '1') ->paginate(4);
这样一来,查询出来的物料都是没有orders_material关联的,而且JSON结果里也不会出现这个关联字段,自然就没有多余的pivot内容了。
方案二:如果必须保留预加载(不推荐,除非有特殊需求)
如果你因为某些业务逻辑必须预加载orders_material,可以在查询后手动隐藏这个字段,或者在模型里配置隐藏:
- 临时隐藏(只针对当前查询):
$material = Material::with(['orders_material','locals']) ->whereDoesntHave('orders_material') ->where('Categoria_id', $idcategory) ->where('SubCategoria_id', $idsubcategory) ->where('requisitado', '0') ->where('estado', '1') ->paginate(4); // 隐藏orders_material字段 $material->getCollection()->makeHidden(['orders_material']);
- 全局隐藏(在Material模型里配置):
class Material extends Model { protected $hidden = ['orders_material']; // ...其他模型代码 }
验证效果
修改后,你再看返回的JSON数据,就不会有多余的pivot关联内容了,同时也能准确筛选出符合条件的物料。
内容的提问来源于stack exchange,提问作者user8563382
相关产品推荐
相关产品推荐

