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

如何通过Eloquent关联获取两次join外order_id对应的shipping_shipment数据

解决方案

你的场景属于多对多跨表筛选,之前使用hasManyThrough的方式参数错误且不符合当前关联场景——hasManyThrough仅适用于链式一对多的关联结构,你可以用多对多关联搭配whereHas方法实现需求,全程无需用到原生表名:

步骤1:为各个模型配置正确的关联

OrderItem 模型新增关联

// app/Models/OrderItem.php
public function shippingShipments()
{
    return $this->belongsToMany(
        ShippingShipment::class,
        OrderItemJoinShippingShipment::class,
        'order_item_id',
        'shipment_id'
    );
}

ShippingShipment 模型新增关联

// app/Models/ShippingShipment.php
public function orderItems()
{
    return $this->belongsToMany(
        OrderItem::class,
        OrderItemJoinShippingShipment::class,
        'shipment_id',
        'order_item_id'
    )->withPivot('order_item_id'); // 加这行可以同时获取中间表的order_item_id字段
}

步骤2:执行查询

直接通过关联筛选即可得到符合order_item.order_id = 13464条件的所有物流单数据:

$shipments = ShippingShipment::whereHas('orderItems', function ($query) {
    $query->where('order_id', 13464);
})->get();

如果需要同时返回中间表的order_item_id字段,和你给出的原生SQL返回结果一致,可以调整查询为:

$shipments = ShippingShipment::whereHas('orderItems', function ($query) {
    $query->where('order_id', 13464);
})->with('orderItems')
  ->get()
  ->flatMap(function ($shipment) {
      return $shipment->orderItems->map(function ($orderItem) use ($shipment) {
          $shipmentData = $shipment->toArray();
          $shipmentData['order_item_id'] = $orderItem->pivot->order_item_id;
          return $shipmentData;
      });
  });

之前的代码不生效的原因

你写的hasManyThrough参数存在两处核心错误:

  • 第二个参数传入了ShippingShipment::class即当前模型本身,不符合中间模型的要求
  • 外键对应关系完全倒置,且hasManyThrough本身就不适用当前多对多中间表的关联场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 22:30:04