Laravel模型中updated事件未触发问题求助
解决Laravel Equipment模型updated事件不触发的问题
问题分析
你的代码里有两个核心问题导致updated事件无法触发:
SoftDeletes使用方式错误
你同时保留了旧版的protected $softDelete = true;属性和softDeletestrait,而Laravel 5.5+版本中,SoftDeletestrait已经完全替代了$softDelete属性,旧属性的存在会干扰模型事件的正常逻辑。批量更新不触发模型事件
Equipment::where('id',$id)->update(...)这种批量更新方式直接执行SQL语句,不会实例化模型,因此不会触发任何模型事件(包括updated),这是Laravel的设计逻辑。
修复步骤
1. 修正模型中的SoftDeletes配置
修改Equipment模型代码,调整trait使用并移除废弃属性:
class Equipment extends Model { use HasFactory, SoftDeletes; // 修正trait名称的大小写 protected $table = 'equipments'; protected $fillable = ['station_id', 'parent_id', 'code', 'name', 'description', 'creator_id','deletor_id','updator_id']; // 移除废弃的$softDelete属性 protected $dates = ['deleted_at']; public static function boot() { parent::boot(); static::updated(function (Equipment $model) { // 建议使用具体模型类型提示 \Log::error('calling refreshTree'); $model->refreshTree(); }); static::created(function (Equipment $model) { $model->refreshTree(); }); static::deleted(function (Equipment $model) { $model->refreshTree(); }); } // 其他方法保持不变... }
2. 确保使用实例化模型的方式更新
只有通过模型实例调用save()方法才会触发updated事件,你的第二种更新方式是正确的,但要确保属性确实发生了变化:
$equipment = Equipment::find($id); // 先检查属性是否修改,避免无意义的save操作 if ($equipment->parent_id != $recordTarget['id']) { $equipment->parent_id = $recordTarget['id']; $equipment->save(); // 此时会触发updated事件 }
3. 验证事件触发状态
可以在save前添加调试代码,确认模型是否处于"脏状态"(即属性已修改):
$equipment = Equipment::find($id); $equipment->parent_id = $recordTarget['id']; dd($equipment->isDirty()); // 返回true表示属性已修改,应该触发事件;返回false则说明值未变化 $equipment->save();
额外说明
如果必须使用批量更新且需要触发事件,可以手动调用模型的updated事件:
$equipment = Equipment::find($id); Equipment::where('id',$id)->update(['parent_id'=>$recordTarget['id']]); // 手动触发updated事件 $equipment->parent_id = $recordTarget['id']; $equipment->fireModelEvent('updated', false);
内容的提问来源于stack exchange,提问作者S.M_Emamian
相关产品推荐
相关产品推荐

