laravel中恢复软删除数据需先启用softdeletes并添加deleted_at字段,再用withtrashed()或onlytrashed()查出记录,最后在事务中调用restore()并联动事件处理。

在 Laravel 中实现模型软删除后的数据恢复,核心是理解 restore() 的触发条件、查询范围和事务安全边界。它不是简单调用一个方法就能“万无一失”,而是一套需前后对齐的配置与操作逻辑。
模型必须启用软删除机制
这是恢复功能存在的前提。缺了这步,restore() 会报错或静默失效。
- 数据库迁移中添加
$table->softDeletes(),确保表里有可为空的deleted_at字段 - 模型类引入
SoftDeletestrait:use Illuminate\Database\Eloquent\SoftDeletes; - 声明
use SoftDeletes;即可,Laravel 6+ 不强制要求$dates = ['deleted_at'],但加上更稳妥,便于 Carbon 时间处理
正确查出已删除的数据再恢复
普通查询(如 Model::find(1) 或 Model::all())默认忽略软删除记录。想恢复,必须先“看见”它们。
-
Model::withTrashed()->find(1):不管是否已删,都尝试查出该 ID 记录 -
Model::onlyTrashed()->where('status', 'draft')->get():只查满足条件的已删数据,适合批量筛选 - 注意:直接用
Model::find(1)->restore()会失败——因为find()查不到已删项,得先用withTrashed()或onlyTrashed()
单条与批量恢复的写法差异
恢复操作本身简单,但调用方式决定是否可控、可回滚、可审计。
- 单条恢复:
$model = Model::withTrashed()->findOrFail(1); $model->restore(); - 批量恢复(推荐分片):
Model::onlyTrashed()->chunkById(100, function ($models) { DB::transaction(fn () => $models->each->restore()); }); - 不要用
Model::onlyTrashed()->restore()这种全局调用——它不走模型事件、难加日志、无法事务包裹,且 Laravel 版本兼容性差
事务保障与事件联动
单纯清空 deleted_at 不够。真实业务中,恢复常需同步更新状态、写日志、刷新缓存或校验唯一性。
- 用
DB::transaction()包裹restore()和后续操作,避免部分成功导致数据不一致 - 监听
restoring和restored事件,在模型中做前置校验或后置清理 - 例如:恢复用户前检查邮箱是否仍唯一;恢复后触发
UserRestored通知权限服务重载角色











