Laravel一对多关联模型添加项成功但未写入数据库求助
问题描述
我一直卡在这个问题上。想通过Update方法从ShipmentRequest模型插入ShipmentRequestItem,以下是我的update方法代码:
public function update(UpdateShipmentRequestRequest $request, $id) { $shipmentRequest = ShipmentRequest::with( 'shipmentRequestItems', )->where('id',$id)->first(); $shipmentRequest->update($request->all()); $validatedData = $request->validated(); $shipmentRequestItems = $validatedData['shipmentRequestItems']; // $shipmentRequest = ShipmentRequest::find($id); $existingItems = []; foreach ($shipmentRequestItems as $value) { DB::beginTransaction(); if (is_array($value)) { $shipmentRequestItem = new ShipmentRequestItem; $shipmentRequestItem->name = $value["name"]; $shipmentRequestItem->quantity = $value["quantity"]; $shipmentRequestItem->shipment_request_id = $shipmentRequest->id; // Save the ShipmentRequestItem to the database $shipmentRequestItem->save(); $shipmentRequest->shipmentRequestItems()->create(['name' => $value['name'], 'quantity'=> $value['quantity']]); $shipmentRequest->shipmentRequestItems()->save($shipmentRequestItem); echo json_encode($shipmentRequest); echo json_encode($shipmentRequestItem); } else { $existingItems[] = $value; } } $shipmentRequest->shipmentRequestItems()->whereNotIn('id', $existingItems)->delete(); $shipmentRequest->refresh(); return new ShipmentRequestResource($shipmentRequest); }
输出$shipmentRequest->shipmentRequestItems()时显示项已成功添加,但数据库表中没有记录,且ID在递增。尝试多种插入方法结果都一样,数据未写入数据库。
解决方法
1. 核心问题:事务未提交
你在循环内开启了事务DB::beginTransaction();,但全程没有执行DB::commit();来提交事务。事务未提交时,所有数据库操作都只是临时的内存状态,不会真正写入数据库;而ID递增是因为自增字段在执行插入语句时就会被占用,不管事务最终是否提交。
2. 冗余操作:重复创建数据
同一个分支里执行了三次插入逻辑:
$shipmentRequestItem->save();$shipmentRequest->shipmentRequestItems()->create(...)$shipmentRequest->shipmentRequestItems()->save($shipmentRequestItem);
这会导致重复生成多条相同记录,完全没必要,保留一种关联创建方式即可。
修正后的代码
public function update(UpdateShipmentRequestRequest $request, $id) { DB::beginTransaction(); // 将事务放在循环外,避免多次开启 try { $shipmentRequest = ShipmentRequest::with('shipmentRequestItems')->findOrFail($id); $shipmentRequest->update($request->all()); $validatedData = $request->validated(); $shipmentRequestItems = $validatedData['shipmentRequestItems']; $existingItems = []; foreach ($shipmentRequestItems as $value) { if (is_array($value)) { // 利用关联关系创建,自动处理外键赋值,无需手动设置shipment_request_id $shipmentRequest->shipmentRequestItems()->create([ 'name' => $value['name'], 'quantity' => $value['quantity'] ]); } else { $existingItems[] = $value; } } // 删除不在现有列表中的关联项 if (!empty($existingItems)) { $shipmentRequest->shipmentRequestItems()->whereNotIn('id', $existingItems)->delete(); } else { // 若没有保留的现有项,删除所有关联项 $shipmentRequest->shipmentRequestItems()->delete(); } $shipmentRequest->refresh(); DB::commit(); // 提交事务,写入数据库 return new ShipmentRequestResource($shipmentRequest); } catch (\Exception $e) { DB::rollBack(); // 发生异常时回滚事务 throw $e; // 抛出异常,交由框架处理错误响应 } }
额外检查项
- 确认
ShipmentRequestItem模型的$fillable属性包含所需字段,否则批量赋值会失败:
class ShipmentRequestItem extends Model { protected $fillable = ['name', 'quantity', 'shipment_request_id']; }
- 检查数据库连接配置,确保操作的是目标数据库;
- 查看Laravel日志文件(
storage/logs/laravel.log),排查是否有隐藏的异常信息。
内容的提问来源于stack exchange,提问作者JackStone
相关产品推荐
相关产品推荐

