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
相关产品推荐
相关产品推荐

