Laravel Eloquent多对多、一对多关联下如何获取各仓库对应的销售数据
问题原因
你当前写法的核心问题是Product模型下的sales关联没有区分仓库维度,当你使用with('products.sales')预加载数据时,会直接拉取指定商品的全量销售记录,不会根据商品所属的仓库过滤sales表的warehouse_id字段,所以才会出现不同仓库下的同一款商品返回完全相同的销售数据的问题。
解决方案
方案1:预加载时加动态过滤(保留原有嵌套结构)
如果你需要保留「仓库→商品→对应仓库的销售记录」的嵌套返回结构,可以在预加载时给嵌套关联加查询条件,匹配中间表的仓库ID即可:
return Warehouse::with(['products' => function ($productQuery) { // 给sales关联加条件,匹配当前仓库的ID $productQuery->with(['sales' => function ($saleQuery) { $saleQuery->whereColumn('sales.warehouse_id', 'warehouse_product.warehouse_id'); }]); }])->get();
这个写法利用了多对多查询时自动关联的warehouse_product中间表,直接关联过滤销售记录的仓库ID,不需要额外传参。
方案2:给仓库新增销售关联(直接拿全仓销售数据)
如果你经常需要查询每个仓库的所有销售数据,更推荐直接给Warehouse模型新增独立的sales关联,用hasManyThrough跨多对多中间表查询:
- 先创建多对多中间表的模型
WarehouseProduct(如果之前没有创建的话) - 在
Warehouse.php中添加关联方法:
public function sales() { return $this->hasManyThrough( Sale::class, WarehouseProduct::class, 'warehouse_id', // 中间表关联仓库的外键 'product_id', // 销售表关联商品的外键 'id', // 仓库表主键 'product_id' // 中间表关联商品的外键 ); }
之后直接用以下代码就能拿到每个仓库对应的所有销售记录,结构更简洁:
return Warehouse::with('sales')->get();
内容的提问来源于stack exchange,提问作者Othmane
相关产品推荐
相关产品推荐

