Laravel怎么实现模型软删除恢复后重置状态_Laravel触发初始化逻辑【方法】

冬晨酱_3109

冬晨酱_3109

2026-03-24

608人浏览

原创

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

laravel怎么实现模型软删除恢复后重置状态_laravel触发初始化逻辑【方法】

软删除恢复后状态没重置,是因为 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() 不存在,硬写会报错。这时候只能手动补逻辑。

Laravel
Laravel

避免常见的Laravel错误:N+1查询、批量赋值、缓存陷阱及队列序列化陷阱。

下载
  • 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 版本、逻辑一目了然。真正难的不是怎么写,而是想清楚哪些字段必须重置、哪些可以保留、以及重置时机是否该由调用方决定。

相关专题

更多
laravel组件介绍
laravel组件介绍

laravel 提供了丰富的组件,包括身份验证、模板引擎、缓存、命令行工具、数据库交互、对象关系映射器、事件处理、文件操作、电子邮件发送、队列管理和数据验证。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

2024.04.09

817

10

laravel中间件介绍
laravel中间件介绍

laravel 中间件分为五种类型:全局、路由、组、终止和自定。想了解更多laravel中间件的相关内容,可以阅读本专题下面的文章。

2024.04.09

795

9

laravel使用的设计模式有哪些
laravel使用的设计模式有哪些

laravel使用的设计模式有:1、单例模式;2、工厂方法模式;3、建造者模式;4、适配器模式;5、装饰器模式;6、策略模式;7、观察者模式。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

2024.04.09

2388

10

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.10

3341

7

laravel入门教程
laravel入门教程

本专题整合了laravel入门教程,想了解更多详细内容,请阅读专题下面的文章。

2025.08.05

4670

22

laravel实战教程
laravel实战教程

本专题整合了laravel实战教程,阅读专题下面的文章了解更多详细内容。

2025.08.05

3116

13

laravel面试题
laravel面试题

本专题整合了laravel面试题相关内容,阅读专题下面的文章了解更多详细内容。

2025.08.05

5969

7

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

2026.03.04

1356

29

Laravel 框架安装指南
Laravel 框架安装指南

本指南详解 Laravel 框架安装全流程,涵盖 PHP 8.1+ 环境配置、Composer 依赖管理工具安装及国内镜像源优化。重点演示使用 composer create-project 命令创建 Laravel 10/11 项目,解决常见安装错误与依赖冲突。从环境搭建到项目初始化,助您快速完成 Laravel 开发环境部署,为后续 Web 应用开发奠定基础。适合 PHP 初学者与框架迁移开发者参考。

2026.04.09

175

6

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
如何安装 Composer
如何安装 Composer

共1课时 | 180人学习

Composer手册
Composer手册

共0课时 | 0人学习