开启 Laravel 软删除需两步:添加 deleted_at 字段(用 $table->softDeletes())并在模型中 use SoftDeletes;恢复用 restore(),查询软删数据需 withTrashed() 或 onlyTrashed(),彻底删除用 forceDelete()。

开启 Laravel 软删除只需两步:加数据库字段 + 在模型中引入 trait;恢复数据则通过 restore() 方法,前提是数据确实处于软删除状态(deleted_at 非空)。
添加 deleted_at 字段到数据表
软删除依赖数据库中一个名为 deleted_at 的 timestamp 类型字段,它必须允许为 NULL。推荐用迁移添加:
- 运行命令生成迁移:
php artisan make:migration add_deleted_at_to_posts_table --table=posts - 在迁移的
up()方法中写:$table->softDeletes(); - 执行迁移:
php artisan migrate
注意:字段名固定为 deleted_at,不能自定义;若表已存在且有唯一索引(如 email),需检查是否因软删除导致重复值冲突(可考虑将唯一索引改为联合索引,含 deleted_at)。
在模型中启用 SoftDeletes
模型需明确声明使用该功能,否则 delete() 仍为硬删除:
- 在模型顶部引入 trait:
use Illuminate\Database\Eloquent\SoftDeletes; - 在类定义中添加:
use SoftDeletes; - 无需额外配置
$dates—— Laravel 10+ 已自动处理deleted_at的时间类型转换
验证是否生效:调用 $post->delete() 后查数据库,可见该行 deleted_at 值已设为当前时间戳,记录未消失。
查询与恢复软删除的数据
默认查询(如 Post::all())自动排除 deleted_at IS NOT NULL 的记录。要操作已软删数据,需显式指定范围:
-
Post::withTrashed()->find(5):查出 ID=5 的记录,无论是否已软删 -
Post::onlyTrashed()->where('title', '草稿')->get():只取已软删且标题含“草稿”的文章 -
$post->restore():将deleted_at设为 NULL,数据重新进入常规查询结果 -
Post::onlyTrashed()->where('id', 5)->restore():支持集合批量恢复
恢复失败常见原因:模型未用 SoftDeletes、未用 withTrashed() 或 onlyTrashed() 查到目标实例、事务中发生异常未回滚。
彻底删除或强制清理
当确认某条软删除数据无需保留,可用 forceDelete() 物理移除:
-
$post->forceDelete():跳过软删除逻辑,直接执行 DELETE SQL -
Post::onlyTrashed()->forceDelete():清空所有软删除记录
注意:此操作不可逆,且不会触发 restoring/restored 事件,但会触发 deleting/deleted 事件。



















