在FastAdmin ThinkPHP5环境下 关联查询 软删除未生效

问题描述

在后台用户列表管理功能中,用户模型(User)已启用软删除(SoftDelete)并实现邀请人关联查询。但在实际查询时,发现主表(fa_user)的软删除条件未生效,导致已软删除的用户仍会被统计和查询出来。


相关代码片段

1. 用户列表查询方法

php 复制代码
/**
 * 查看
 */
public function index()
{
    $this->relationSearch = true;
    //设置过滤方法
    $this->request->filter(['strip_tags', 'trim']);
    if ($this->request->isAjax()) {
        //如果发送的来源是Selectpage,则转发到Selectpage
        if ($this->request->request('keyField')) {
            return $this->selectpage();
        }
        list($where, $sort, $order, $offset, $limit) = $this->buildparams();
        $list = $this->model
            ->with(['withparent'])
            ->where($where)
            ->order($sort, $order)
            ->paginate($limit);
        $result = array("total" => $list->total(), "rows" => $list->items());

        return json($result);
    }
    return $this->view->fetch();
}

2. 用户模型定义

php 复制代码
class User extends Model
{
    use SoftDelete;
    // 表名
    protected $name = 'user';
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';
    
    /**
    * 关联邀请人
    **/
    public function withparent()
    {
        return $this->belongsTo('User', 'parent_user_id', 'id', [], 'LEFT')->field('id,username,mobile,nickname')->setEagerlyType(0);
    }
 }

问题分析

  • 实际生成的 SQL 只对关联表(withparent)添加了软删除过滤(withparent.deletetime IS NULL),主表(fa_user)未添加软删除条件(user.deletetime IS NULL)。
  • 结果:主表已软删除的用户仍会被统计和查询出来。
    示例 SQL:
php 复制代码
SELECT
	COUNT(*) AS tp_count
FROM
	`fa_user` `user`
	LEFT JOIN `fa_user` `withparent` ON `user`.`parent_user_id` = `withparent`.`id`
WHERE
	`withparent`.`deletetime` IS NULL
LIMIT 1
  • 如果去掉关联邀请人查询,则主表软删除过滤正常。
  • 该情况未在官方文档中明确说明。

解决方案

手动增加主表软删除过滤条件,即在查询中添加 whereNull('user.deletetime'):

php 复制代码
$list = $this->model
    ->with(['withparent'])
    ->where($where)
    ->whereNull('user.deletetime')
    ->order($sort, $order)
    ->paginate($limit);

最终生成 SQL:

sql 复制代码
SELECT
	COUNT(*) AS tp_count
FROM
	`fa_user` `user`
	LEFT JOIN `fa_user` `withparent` ON `user`.`parent_user_id` = `withparent`.`id`
WHERE (`user`.`deletetime` IS NULL)
	AND `withparent`.`deletetime` IS NULL
LIMIT 1

总结与建议

  • 主表软删除过滤需手动添加:在涉及关联查询时,需注意主表软删除条件不会自动生效,需手动补充。
  • 建议:在类似场景下,务必检查 SQL 生成结果,确保软删除逻辑完整覆盖主表与关联表,避免数据异常。

相关推荐
两个人的幸福9 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
BingoGo11 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack11 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户30745969820712 天前
PHP 扩展——从入门到理解
php
鹏仔先生13 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
云水一下13 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
xingpanvip13 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
酉鬼女又兒13 天前
零基础入门计算机网络运输层:端到端通信核心作用、端口号分类规则、复用分用工作机制及UDP与TCP协议全方位对比详解
网络·网络协议·tcp/ip·计算机网络·考研·udp·php
dog25013 天前
不要再继续优化 TCP
网络协议·tcp/ip·php
Channing Lewis13 天前
PHP 解析 Excel 的那些坑:一次“行号错位”引发的数据丢失
开发语言·php·excel