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

Laravel whereDoesntHave失效求助:筛选无关联的物料数据

解决物料筛选中多余pivot关联的问题

我帮你分析下当前代码的问题,以及怎么修复:

问题出在哪?

  1. whereDoesntHave的逻辑错误:你现在在whereDoesntHave里加了->where('Material_id', null),这完全偏离了需求——你要的是没有任何orders_material关联的物料,但这个条件是在找“关联存在但Material_id为空”的情况,逻辑完全反了。
  2. 不必要的预加载关联:你用了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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:16:25