Laravel中StudentSchedule Observer的updated事件未触发问题
Laravel Observer updated事件不触发问题
问题概述
StudentSchedule模型的Observer中,created事件可正常触发并记录日志,但updated事件完全不执行,已确认Observer注册流程正确。
相关代码
ScheduleObserver代码
public function created(StudentSchedule $student_schedule) { Log::info('created log'); $student = $student_schedule->student()->get()->first(); $schedule = $student_schedule->schedule()->get()->first()->subject->subject; Logger::createLog("Student Schedule Added for " . $student->first_name . " " . $student->last_name . " '" . $schedule->name . "'"); } /** * Handle the student schedule "updated" event. * * @param \App\Models\Student\Schedule $student_schedule * @return void */ public function updated(StudentSchedule $student_schedule) { Log::info('updated log'); // 注释的业务逻辑代码 }
控制器更新代码
public function dropSchedules(Request $request) { StudentSchedule::whereIn('id', $request->student_schedules)->update(['final_grade' => 'DRP']); return response()->json([ 'message' => 'Student schedules successfully dropped.' ], 200); }
Observer注册代码(ObserverProvider)
class ObserverProvider extends ServiceProvider { public function boot() { StudentSchedule::observe(StudentScheduleObserver::class); } }
问题原因
你使用的是查询构造器的批量更新方法:StudentSchedule::whereIn()->update(),这种方式直接生成SQL语句操作数据库,不会加载任何Eloquent模型实例,因此不会触发模型的updated事件,自然也不会执行Observer中的updated方法。
而created事件正常工作,是因为创建模型时依赖Eloquent的create()/模型实例save()方法,会完整触发模型生命周期事件。
解决方案
要触发Observer的updated事件,必须通过Eloquent模型实例执行更新操作,以下是两种可行方式:
方式1:查询模型实例后逐个更新(适合数据量不大的场景)
修改控制器代码,先通过get()获取模型集合,再遍历调用update():
public function dropSchedules(Request $request) { StudentSchedule::whereIn('id', $request->student_schedules)->get()->each(function ($schedule) { $schedule->update(['final_grade' => 'DRP']); }); return response()->json([ 'message' => 'Student schedules successfully dropped.' ], 200); }
方式2:手动触发事件(适合大数据量场景,避免内存占用过高)
如果数据量较大,逐个加载模型会占用过多内存,可以在批量更新后手动触发事件:
public function dropSchedules(Request $request) { $ids = $request->student_schedules; // 批量更新数据库 StudentSchedule::whereIn('id', $ids)->update(['final_grade' => 'DRP']); // 手动触发updated事件 foreach ($ids as $id) { $schedule = StudentSchedule::find($id); if ($schedule) { event(new \Illuminate\Database\Events\Updated($schedule)); // 或者直接调用Observer的方法 // app(StudentScheduleObserver::class)->updated($schedule); } } return response()->json([ 'message' => 'Student schedules successfully dropped.' ], 200); }
验证结果
修改后,Observer中的updated方法会被触发,Log::info('updated log')会正常输出日志,后续业务逻辑也能正常执行。
内容的提问来源于stack exchange,提问作者Kael
相关产品推荐
相关产品推荐

