Laravel观察者created事件无法获取Order模型全部属性如何解决
问题原因
Laravel Eloquent 的 created 事件触发时机为模型首次插入数据库完成的瞬间,你遇到的属性缺失是创建订单的执行顺序导致的:
- 从日志可以确认,
created触发时订单的金额字段均为 0、商品关联为空、无status字段,说明你的代码执行顺序是:先写入订单基础字段(生成订单ID)→ 触发created事件 → 后续补充status等字段、关联商品、计算金额 → 保存订单触发updated事件。created阶段后续的赋值、关联操作还未执行,自然拿不到对应的属性。 - 若你确认创建时已经传入了所有字段仍有缺失,可检查模型的
$fillable属性是否将缺失字段加入可批量赋值列表,或$hidden属性是否将对应字段设置为隐藏。
解决方案
方案1:调整订单创建逻辑(最优)
提前组装好所有订单字段、准备好关联数据,一次性完成创建写入,避免创建后二次更新:
// 提前组装所有必填字段 $orderData = [ 'customer_id' => 1, 'status' => 'Delivered', 'vat' => 5, 'sub_total' => 24.98, 'vat_in_money' => 1.25, 'total_price' => 26.23, // 其余需要的字段全部提前赋值 ]; // 创建订单 $order = Order::create($orderData); // 同步关联商品,可直接使用创建好的订单ID $order->products()->sync($productsData);
方案2:替换监听事件为 saved
如果你的业务逻辑必须先创建基础订单再补充数据,可以将监听的 created 事件替换为 saved,并通过 wasRecentlyCreated 判断是否为首次创建,同时主动刷新模型获取完整数据:
class OrderObserver { public function saved($model) { // 仅首次创建时执行业务逻辑 if ($model->wasRecentlyCreated) { // 从数据库刷新模型,拉取最新的字段与关联数据 $model->refresh(); Log::alert("observer" , [$model]); // 你的其余业务逻辑 } } public function updated($model) { Log::alert("observer" , [$model]); } }
方案3:延迟处理创建逻辑(特殊场景适用)
如果你的订单补充字段操作是异步执行的,可以将 created 触发后的业务逻辑放入延迟队列,等所有字段写入完成后再执行。
内容的提问来源于stack exchange,提问作者RazaUsman_k
相关产品推荐
相关产品推荐

