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

删除用户模型前检查使用情况的优化方案咨询

简洁实现阻止删除被关联引用的User条目

针对你当前重复编写大量关联计数方法的问题,这里提供两种简洁的优化方案,避免冗余代码:

方案一:封装通用计数方法,维护模型列表

在User模型中封装一个通用方法,用于统计单个模型中三个字段的关联数量,然后在in_use()中批量处理所有需要检查的模型:

// User模型中新增通用方法
protected function countRelated(string $modelClass): int
{
    return $modelClass::where('created_by', $this->id)
        ->orWhere('modified_by', $this->id)
        ->orWhere('deleted_by', $this->id)
        ->count();
}

// 重写in_use方法
public function in_use(): int
{
    // 列出所有需要检查的关联模型类
    $relatedModels = [
        Operator::class,
        Source::class,
        UnitType::class,
        // 继续添加其他20+个模型类
    ];

    $totalCount = 0;
    foreach ($relatedModels as $model) {
        $totalCount += $this->countRelated($model);
    }

    return $totalCount;
}

这种方式只需要维护$relatedModels数组即可,无需为每个模型单独编写重复方法,代码简洁易维护。

方案二:联合查询优化性能

如果关联表数量较多(20+张),方案一的循环查询会产生多次数据库请求,性能略差。可以使用unionAll合并查询,只执行一次SQL请求:

public function in_use(): int
{
    // 列出所有需要检查的关联表名(对应数据库中的表名)
    $relatedTables = [
        'operators',
        'sources',
        'unit_types',
        // 继续添加其他20+个表名
    ];

    $unionQuery = null;
    foreach ($relatedTables as $table) {
        $subQuery = \DB::table($table)
            ->selectRaw('1')
            ->where('created_by', $this->id)
            ->orWhere('modified_by', $this->id)
            ->orWhere('deleted_by', $this->id);

        if (!$unionQuery) {
            $unionQuery = $subQuery;
        } else {
            $unionQuery->unionAll($subQuery);
        }
    }

    return $unionQuery ? $unionQuery->count() : 0;
}

这个方案通过合并子查询,将多次数据库请求减少为一次,大幅提升查询效率,适合表数量较多的场景。

额外建议:数据库层面添加约束

除了应用层检查,还可以在数据库中为每张表的created_by、modified_by、deleted_by字段添加外键约束,设置ON DELETE RESTRICT,这样数据库层面会直接阻止删除被引用的User条目,和应用层检查形成双重保障。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 16:57:42