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

Laravel软删除deleted_at与子查询兼容问题排查与解决

Laravel子查询与软删除Trait的兼容问题

基础信息

  • 应用架构:Repository + Service
  • 使用版本:
    • Laravel v10.16.1
    • PHP 8.1
  • 数据表字段:包含deleted_at、updated_at、created_at字段

问题描述

启用软删除Trait后,期望deleted_at自动过滤已删除数据,但执行包含子查询的代码时触发报错:

错误代码示例

class UserRepository {
    ...

    public function getWhere(array $columns, Builder $where)
    {
        $query = $this->model
            ->newQuery()
            ->when($where, function (Builder $query) use ($where) {
                $query->fromSub($where, 'sub');
            });

        return $query->get($columns);
    }

    ...
}

报错信息

ERROR: `'deleted_at' column does not exists`

问题SQL分析

生成的SQL语句如下:

SELECT * FROM (SELECT * FROM `users` WHERE `name`='john') AS `sub` WHERE `users`.`deleted_at` IS NULL

deleted_at字段实际存在于数据库,但Laravel错误地引用了原表users的deleted_at,而非子查询别名sub对应的字段,导致报错。

解决方案

移除软删除Trait的自动处理逻辑,改为手动指定deleted_at的表前缀:

class UserRepository {
    ...
    
    public function getWhere(array $columns, Builder $where)
    {
        $prefix = $this->model->getTable();
        $query = $this->model
            ->newQuery()
            ->when($where, function (Builder $query) use ($where, &$prefix) {
                $prefix = 'sub';
                $query->fromSub($where, $prefix);
            });

        $query->whereNull($prefix . '.deleted_at');

        return $query->get($columns);
    }

    ...
}

补充说明

此前误描述了updated_at相关问题,实际仅子查询与deleted_at的自动处理存在兼容性问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 11:41:00