Laravel多表关联查询:实现订单含商品及子商品结构
解决方案
1. 补充缺失的模型关联
首先完善ProductRelation模型,添加关联到COMPONENT类型子商品的关系:
// app/Models/ProductRelation.php public function component() { return $this->belongsTo(Product::class, 'child_product_id'); }
2. 查询订单并预加载关联数据
利用Laravel关联预加载避免N+1查询,一次性获取订单1011的全量关联数据:
$order = Order::with([ 'orderProducts.product', 'orderProducts.product.sub_products.component' ])->find(1011);
3. 整理为指定嵌套结构
筛选出ITEM类型商品,并为每个ITEM匹配当前订单中对应的COMPONENT子商品:
// 提取订单下所有商品记录 $allOrderProducts = $order->orderProducts; // 构建最终输出结构 $orderDetails = [ 'order_id' => $order->id, 'order_no' => $order->order_no, 'created_at' => $order->created_at->toDateTimeString(), // 按需添加其他订单字段 'items' => [] ]; foreach ($allOrderProducts as $op) { // 仅处理ITEM类型且无父商品的记录 if ($op->product->type === 'ITEM' && is_null($op->parent_product_id)) { // 获取当前ITEM的子商品关联关系 $componentRelations = $op->product->sub_products; // 从订单商品中筛选对应COMPONENT子商品 $components = $allOrderProducts->filter(function ($componentOp) use ($componentRelations) { return $componentOp->product->type === 'COMPONENT' && $componentRelations->pluck('child_product_id')->contains($componentOp->product_id); })->map(function ($componentOp) { return [ 'product_id' => $componentOp->product_id, 'name' => $componentOp->product->name, 'type' => $componentOp->product->type, 'quantity' => $componentOp->quantity, 'price' => $componentOp->price // 按需添加其他子商品字段 ]; })->values()->toArray(); // 组装ITEM商品信息 $orderDetails['items'][] = [ 'product_id' => $op->product_id, 'name' => $op->product->name, 'type' => $op->product->type, 'quantity' => $op->quantity, 'price' => $op->price, // 按需添加其他ITEM商品字段 'components' => $components ]; } } // 返回结构化数据 return $orderDetails;
关键说明
- 预加载
orderProducts.product.sub_products.component确保一次性获取所有关联层级数据,提升查询效率。 - 通过
filter方法匹配订单内实际存在的COMPONENT子商品,保证数据与订单实际内容一致。 - 可根据业务需求自由调整返回字段,如添加商品SKU、订单状态等信息。
内容的提问来源于stack exchange,提问作者Muntasir Hasan
相关产品推荐
相关产品推荐

