删除用户模型前检查使用情况的优化方案咨询
简洁实现阻止删除被关联引用的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
相关产品推荐
相关产品推荐

