Laravel 12 + Rappasoft 表格组件:解决订单列表订单项重复问题,仅显示首条订单项的租赁时间
Laravel 12 + Rappasoft 表格组件:解决订单列表订单项重复问题,仅显示首条订单项的租赁时间
看起来你遇到的问题是由于订单关联了多个订单项,导致表格渲染时出现重复的订单行,或是设备列显示了所有订单项的信息。让我们一步步解决这个问题:
1. 优化 Order 模型的 firstItem 关联
你已经定义了获取首个订单项的关联,但多余的访问器可能导致不必要的查询或逻辑混淆。建议移除冗余的访问器,因为 hasOne 关联本身就会返回单个实例:
// Order 模型 public function firstItem() { return $this->hasOne(OrderItem::class)->oldestOfMany(); } // 移除以下多余的访问器 // public function getFirstItemAttribute() // { // return $this->firstItem()->first(); // }
2. 调整表格查询逻辑,避免重复行
在你的订单表格类中,确保查询时只预加载首个订单项而非所有订单项,这样可以避免笛卡尔积导致的重复订单行,同时减少不必要的数据库查询:
// 你的 OrderTable 类中的 query 方法 public function query(): Builder { return Order::query() // 仅预加载需要的关联,避免加载所有订单项 ->with([ 'client', 'firstItem.equipmentUnit.equipment' // 预加载首个订单项的设备单元和设备信息 ]) // 明确只选择订单表的字段,防止关联查询导致的重复数据 ->select('orders.*'); }
3. 修改表格列,仅显示首个订单项的信息
当前你的设备列遍历了所有订单项,导致显示所有设备。我们需要改成只取首个订单项的设备信息,同时处理空值场景:
public function columns(): array { return [ Column::make('ID', 'id') ->sortable() ->searchable(), DateColumn::make('Rental date', 'firstItem.rented_at') ->inputFormat('Y-m-d H:i:s') ->outputFormat('d.m.Y') ->sortable(), Column::make('Client', 'client.name') ->searchable(), Column::make('Phone', 'client.phone') ->searchable(), Column::make('Equipment') ->label(function ($row) { // 处理没有订单项的空场景 if (!$row->firstItem?->equipmentUnit) { return '-'; } $unit = $row->firstItem->equipmentUnit; return $unit->equipment->title . ' (' . $unit->code . ')'; }) ->html(), Column::make('Action') ->label(fn($row) => view('livewire.orders.table-actions', ['id' => $row->id, 'status' => $row->status])) ->html(), ]; }
4. 额外修复:模型关联的笔误
注意到你在 EquipmentUnit 模型里有一些关联笔误,可能影响后续的关联查询,建议修正:
// EquipmentUnit 模型 public function model() { return $this->belongsTo(EquipmentModel::class, 'equipment_model_id'); } // 修复重复的 equipment 关联(根据业务逻辑调整,示例为关联到 Equipment 模型) public function equipment() { return $this->belongsTo(Equipment::class, 'equipment_id'); } // 修复 orders 关联:EquipmentUnit 与 Order 是通过 OrderItem 间接关联的,需用 hasManyThrough public function orders() { return $this->hasManyThrough( Order::class, OrderItem::class, 'equipment_unit_id', // OrderItem 表关联 EquipmentUnit 的外键 'id', // Order 表的主键 'id', // EquipmentUnit 表的主键 'order_id' // OrderItem 表关联 Order 的外键 ); }
通过以上步骤,你的表格应该只会显示每个订单的一行数据,且仅展示首个订单项的租赁日期和设备信息,不会再出现重复行的问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

