LaravelModel模型_软删除SoftDeletes功能使用【详解】
发布:smiling 来源: PHP粉丝网 添加日期:2026-05-23 17:54:23 浏览: 评论:0
软删除本质是标记而非删除,需模型启用SoftDeletes trait且数据库存在匹配类型的deleted_at字段;trashed()是判断软删状态的唯一可靠方法,withTrashed()和onlyTrashed()用于显式查询,restore()失败多因字段配置或事务问题。
软删除不是“删了还能找回来”,而是压根没删——只是给记录打了个 deleted_at 时间戳标记。只要模型正确启用 SoftDeletes,且数据库字段存在、类型匹配,后续所有行为才可预期。
怎么确认一条记录是否已被软删除
不能靠肉眼看数据库字段,也不能依赖 find() 是否返回结果——因为默认查询会自动过滤掉软删数据。
$user->trashed() 是唯一可靠判断方式:返回 true 表示该模型实例的 deleted_at 非空
必须先查出模型实例(哪怕已软删),再调用该方法。例如:User::withTrashed()->find(123)->trashed()
如果直接用 User::find(123),返回 null 时你根本不知道是“不存在”还是“已被软删”
注意:trashed() 是实例方法,不能在查询构造器上链式调用(如 User::where(...)->trashed() 会报错)
查不到软删记录?先看 withTrashed() 和 onlyTrashed() 用对没
这是最常卡住人的地方:默认所有 Eloquent 查询都带 WHERE deleted_at IS NULL 全局作用域。
User::all()、User::find(1)、User::where(...)->get() —— 全都不含软删数据
要查“全部(含软删)”,必须加 withTrashed():User::withTrashed()->where('email', 'x@y.z')->get()
要查“仅软删的”,必须加 onlyTrashed():User::onlyTrashed()->where('name', 'test')->first()
onlyTrashed()->find(1) 返回 null?不是代码错,而是这条记录根本没被软删过(可能硬删了,或 delete() 根本没执行成功)
restore() 失败却没报错?重点排查这三处
$user->restore() 看似简单,但失败时往往静默吞掉异常,导致你以为恢复成功了,其实 deleted_at 还在库里。
检查数据库字段是否被设为 NOT NULL(比如误加了 DEFAULT CURRENT_TIMESTAMP),导致 UPDATE 时无法写入 NULL
检查模型事件钩子:restoring 或 restored 中是否有逻辑抛出异常或返回 false,中断了流程。
事务中调用后没 commit,或者外层事务被 rollback,查库时自然看不到变化
批量调用 User::onlyTrashed()->where(...)->restore() 不会触发单个模型的 restored 事件,需手动遍历 + 实例调用
自定义 deleted_at 字段名和类型兼容性
别只改 DELETED_AT 常量就完事,Laravel 对字段类型和解析逻辑很敏感。
自定义字段名必须配合 protected $dates = ['my_deleted_at'],否则 restore() 可能清不掉值
Laravel 8+ 要求 deleted_at 必须是 TIMESTAMP NULL,用 DATETIME 会导致 restore() 失败且无提示
如果在 $casts 里写了 'deleted_at' => 'date',会覆盖框架内置的时间处理逻辑,破坏 trashed() 判断
迁移中务必用 $table->softDeletes(),而不是手写 $table->timestamp('deleted_at')->nullable()(虽等效,但少了一层兼容性保障)
真正容易被忽略的是:软删除生效的前提不是“用了 trait”,而是“trait + 字段存在 + 字段类型正确 + 没被其他配置意外覆盖”。任何一环断开,trashed() 就可能永远返回 false,而你还在奇怪为什么删不掉数据。
Tags: LaravelModel 软删除SoftDeletes
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)
