Laravel 8 如何用内置规则简化复合UNIQUE唯一键校验
Laravel 联合唯一索引校验简化方案
不需要手动写$validator->after()闭包查库,Laravel 内置的unique验证规则原生支持附加查询条件,直接就能实现复合唯一键校验,代码比手写闭包简洁很多。
核心实现
定义验证规则时,给unique规则链式调用where方法,传入联合索引的其他字段匹配逻辑即可,示例:
use Illuminate\Validation\Rule; $validated = $request->validate([ 'some_id' => 'required|integer', 'external_id' => [ 'required', 'string', // 校验逻辑:相同some_id下,external_id不能重复 Rule::unique('my_models')->where(function ($query) use ($request) { $query->where('some_id', $request->input('some_id')); }) ], ]);
这段逻辑和你手写闭包的判断效果完全一致:自动查询my_models表中是否存在external_id和some_id同时匹配请求值的记录,存在就抛出验证错误,不需要额外写重复的查库代码。
编辑场景适配
如果是更新数据的场景,追加ignore()方法排除当前编辑的记录本身即可,避免把当前记录误判为重复:
Rule::unique('my_models') ->ignore($currentEditModel->id) // 传入当前记录的主键ID ->where(fn($q) => $q->where('some_id', $request->input('some_id')))
关于exclude_if、unless规则的说明
这两个规则属于条件跳过校验类规则,作用是满足指定条件时,直接跳过当前字段的所有校验逻辑,用来处理「字段要不要参与校验」的判断,本身不具备重复值校验能力,不适合用在复合唯一键校验场景。
注意事项
应用层的验证无法覆盖并发请求的竞态场景,一定要保留数据库层面的联合UNIQUE索引,从存储层彻底杜绝重复数据写入。
内容的提问来源于stack exchange,提问作者pszaba
相关产品推荐
相关产品推荐

