软删除恢复后状态未重置,是因为 restore() 默认不触发模型事件;需改用 restorewithevents()、手动启用 restored 事件监听,或封装 restoreandreset() 方法主动重置。

软删除恢复后状态没重置,是因为 restore() 不触发模型事件
很多人以为调用 restore() 会像 save() 那样走完整的生命周期(比如触发 updating、updated),但实际它只更新 deleted_at 字段,不触发任何模型事件。所以你在 updating 里写的初始化逻辑根本不会执行。
常见错误现象:restore() 后字段还是软删除前的值,比如 status 仍是 "archived",updated_at 没刷新,关联缓存也没清。
- 必须手动触发状态重置,不能依赖事件钩子
- 别在
boot()里监听restoring/restored就完事——它们存在,但默认不激活,得显式启用 -
restored事件只有在模型启用了事件调度(且未禁用)时才生效,而 Laravel 默认对restore()是关闭事件的,除非你用的是withTrashed()->restore()或显式调用restoreWithEvents()(Laravel 10.29+)
用 restored 事件重置状态,但得先确保它真的被触发
不是写了监听就自动生效。Laravel 的 restore() 方法默认跳过事件,要让它走事件流,有两个办法:
- 改用
restoreWithEvents()(Laravel ≥10.29),它等价于restore()+ 强制触发事件 - 或者手动调用
fireModelEvent('restored', false),但更推荐前者 - 在模型中启用事件:确认没调用
unsetEventDispatcher(),且$dispatchesEvents数组里有'restored' => YourRestoredListener::class
示例(Laravel 10.30+):
// 在模型中
protected $dispatchesEvents = [
'restored' => ProductRestored::class,
];
// 监听器里重置字段
class ProductRestored
{
public function handle(Product $product)
{
$product->status = 'active';
$product->updated_at = now();
$product->saveQuietly(); // 避免再次触发事件
}
}
restore() 和 restoreWithEvents() 的兼容性与性能差异
如果你项目还在 Laravel 9 或 10.28 及以下,restoreWithEvents() 不存在,硬写会报错。这时候只能手动补逻辑。
-
restore():快,纯 SQL 更新deleted_at,无额外查询,适合批量恢复且无需初始化的场景 -
restoreWithEvents():多一次模型加载 + 事件分发,单条记录影响不大,但批量时可能明显变慢(尤其监听器里有 DB 查询或 HTTP 调用) - PHP 版本和 Laravel 小版本要核对清楚——
restoreWithEvents()是 10.29 新增,不是 LTS 版本自带功能
别为了“统一写法”强行升级 Laravel,先看业务是否真需要每次恢复都重置状态。有些场景(如后台人工恢复)值得加,但定时任务批量恢复可能更适合用原生 SQL + 手动更新。
最稳的兜底方案:恢复后立刻手动重置,不依赖事件机制
当你要 100% 控制行为、跨 Laravel 版本、或逻辑复杂到监听器不好维护时,直接在业务层做是最可靠的。
- 不要在控制器里写一堆
$model->xxx = yyy,封装成模型方法,比如restoreAndReset() - 用
saveQuietly()避免二次触发事件(包括saving、updating) - 如果涉及关联数据重置(比如清空软删除时生成的归档记录),一定要在事务里做,否则恢复一半失败会导致状态不一致
示例:
public function restoreAndReset()
{
$this->restore();
$this->status = 'active';
$this->last_restored_at = now();
$this->saveQuietly();
Cache::forget("product_{$this->id}");
}
这个方法不依赖事件配置、不挑 Laravel 版本、逻辑一目了然。真正难的不是怎么写,而是想清楚哪些字段必须重置、哪些可以保留、以及重置时机是否该由调用方决定。











