Laravel 6搭配Voyager时部分模型deleted事件未触发如何排查修复?
问题排查与修复方案
1. 排查级联删除带来的事件触发问题
- Laravel的Eloquent模型事件仅在通过Eloquent实例调用删除方法时生效,数据库层面定义的级联删除是直接在数据库层执行SQL,不会经过Eloquent逻辑,因此不会触发
deleted事件。 - 验证方法:手动执行Eloquent删除逻辑测试:
如果此时$modelB = \App\Models\ModelB::find(1); // 替换为实际模型B的命名空间 $modelB->delete();deleted事件正常触发,即可确认问题由数据库级联删除导致。 - 修复方案:
- 方案一:移除迁移文件中的数据库级联删除配置,改用Eloquent层面的关联删除,Laravel 6可在父模型的
deleted事件中手动删除关联的模型B数据。 - 方案二:如果必须保留数据库级联删除,将自定义逻辑迁移到数据库触发器中,或者在触发级联删除的父模型的
deleted事件中同步执行模型B对应的自定义操作。
- 方案一:移除迁移文件中的数据库级联删除配置,改用Eloquent层面的关联删除,Laravel 6可在父模型的
2. 排查父类Boot方法的冲突问题
- 模型B继承自
\TCG\Voyager\Models\User,如果父类的boot方法存在事件拦截逻辑,或者子类的boot方法没有被正确加载,都会导致deleted事件不触发。 - 验证方法:在模型B的
boot方法、deleted事件回调中分别添加日志输出,确认boot方法是否被正常加载,事件回调是否被调用。同时检查Voyager原生User模型的源码,确认是否存在deleting事件返回false中断后续事件流程的逻辑。 - 修复方案:
- 确认模型B的
boot方法拼写正确,且第一行必须调用parent::boot();。 - 如果父类存在事件拦截逻辑,可以给自定义事件设置更高的优先级:
static::deleted(function($model) { someaction(); }, 99); // 数值越大优先级越高
- 确认模型B的
3. 其他通用排查点
- 检查Voyager后台删除模型B条目时,是否直接调用了查询构建器的
delete()方法,查询构建器的删除操作不会触发Eloquent模型事件。 - 如果模型B使用了软删除Trait,普通删除触发的是
softDeleted事件而非deleted事件,需要替换事件监听类型。 - 检查模型B是否配置了
$dispatchesEvents属性覆盖了默认的事件映射,或者有全局作用域拦截了删除操作。
内容的提问来源于stack exchange,提问作者moonvader
相关产品推荐
相关产品推荐

