You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel:设置未来deleted_at后模型被误判软删除,如何解决?

问题:Laravel Eloquent 软删除提前判定异常

我创建User模型实例时,将deleted_at字段设为当前时间加1小时,原本预期时间到期后自动触发软删除,但现在Eloquent直接把这条记录判定为已软删除状态。要求不将deleted_at设为null的前提下解决该问题。

当前现状

  • 有效查询(能获取到记录):
$user = User::withTrashed()->where('id',15)->first();
  • 无效查询(返回null):
$user = User::where('id',15)->first(); // 返回null

模型中设置deleted_at的代码

public static function boot()
{
    parent::boot();

    static::creating(function ($model) {
            $model->deleted_at = now()->addHour();
    });
}

解决方案

Laravel默认的软删除逻辑是只要deleted_at不为null,就判定为已删除,所以要修改这个规则,让它只排除deleted_at小于等于当前时间的记录。直接在User模型中自定义全局作用域替换默认约束即可:

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletes;

class User extends Model
{
    use SoftDeletes;

    protected static function boot()
    {
        parent::boot();

        // 替换默认软删除全局作用域
        static::addGlobalScope('softDelete', function (Builder $builder) {
            $builder->where(function ($query) {
                // 保留未删除(deleted_at为null)和未到删除时间(deleted_at>当前时间)的记录
                $query->whereNull('deleted_at')
                      ->orWhere('deleted_at', '>', now());
            });
        });

        static::creating(function ($model) {
            $model->deleted_at = now()->addHour();
        });
    }
}

说明

  • 修改后,默认查询(不用withTrashed)会正常返回deleted_at大于当前时间的记录,直到时间到期后,该记录才会被自动过滤,此时需要用withTrashed才能查到。
  • 手动调用delete()方法时,Laravel会把deleted_at设为当前时间,此时该记录会立即被判定为已软删除,符合常规操作逻辑。

内容的提问来源于stack exchange,提问作者Christian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 02:38:19