You need to enable JavaScript to run this app. Laravel如何在whereHas中对pivot中间表加where条件查询未关联指定Item的商品
优惠活动
大模型
产品
解决方案
定价
更多

Laravel如何在whereHas中对pivot中间表加where条件查询未关联指定Item的商品

解决方案

核心思路

  • 你需要查询不存在与指定Item的关联关系的Product,对应Eloquent的whereDoesntHave方法,而非whereHas
  • 在关联闭包内可以直接引用中间表的字段名做条件筛选
  • 需先修正关联定义,适配Item模型非默认的主键字段

步骤1:修正Product模型的关联定义

因为你的Item模型主键为item_id而非默认的id,需要在关联方法中指定关联外键,否则关联查询会出错:

// Product模型
public function items(){
      return $this->belongsToMany(Item::class,'product_items', 'product_id', 'item_id');
}

步骤2:实现查询作用域

// Product模型中新增本地作用域
public function scopeGetProductThatIsNotOccupiedByItem($query, ?int $itemId = null)
{
    return $query->when($itemId, function ($query) use ($itemId) {
        $query->whereDoesntHave('items', function ($q) use ($itemId) {
            // 直接对中间表product_items的字段做条件判断
            $q->where('product_items.item_id', $itemId);
        });
    });
}

使用示例

// 查询未被item_id=5关联的商品
$products = Product::getProductThatIsNotOccupiedByItem(5)->get();

// 不传参数时返回所有商品,符合「指定Item未关联任何商品时返回全部」的需求
$allProducts = Product::getProductThatIsNotOccupiedByItem()->get();

补充说明

如果需要在whereHas场景下筛选中间表条件,写法和上面一致,直接在闭包内指定中间表字段即可:

// 示例:查询已经和指定Item关联的商品
$occupiedProducts = Product::whereHas('items', function ($q) use ($itemId) {
    $q->where('product_items.item_id', $itemId);
})->get();

内容的提问来源于stack exchange,提问作者Miracle Hades

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 12:36:03