
本文介绍如何使用 laravel 的 `rule::unique()` 方法结合 `where()` 条件,实现“仅当某关联字段满足特定值时才校验唯一性”的复合验证逻辑,例如确保 `document_usu` 在 `rol_usu = 2` 的用户中全局唯一。
在 Laravel 表单验证中,基础的 unique:table,column 规则仅支持简单表字段去重。但实际业务中常需更精细的约束——比如仅对角色为管理员(rol_usu = 2)的用户校验身份证号(document_usu)是否重复,而其他角色可重复。此时,必须借助 Illuminate\Validation\Rule 类提供的链式条件查询能力。
✅ 正确做法是引入 Rule 门面,并使用 where() 方法动态添加 SQL WHERE 子句:
use Illuminate\Validation\Rule;
// 在控制器或 Request 类的 rules() 方法中
public function rules()
{
return [
'document_usu' => [
'required',
Rule::unique('users', 'document_usu')
->where(fn ($query) => $query->where('rol_usu', 2)),
],
];
}? 注意事项:
- Rule::unique() 第二个参数明确指定校验字段名(如 'document_usu'),避免因默认推断导致错误;
- where() 接收闭包,内部 $query 是 Eloquent 查询构造器实例,可链式调用任意 where* 方法(如 whereNotIn, whereNull);
- 若需排除当前更新记录(编辑场景),应追加 ignore($id, $column),例如:
->ignore($this->route('user')->id, 'id'); - 该规则仅作用于数据库层,不替代前端防重复提交或唯一索引——强烈建议同时在数据库添加复合唯一索引:
ALTER TABLE users ADD UNIQUE INDEX unique_document_rol2 (document_usu, rol_usu);
? 小结:通过 Rule::unique()->where(),你无需自定义验证规则即可优雅实现多条件唯一性校验,兼顾可读性、可维护性与性能。这是 Laravel 验证器深度集成 Eloquent 查询能力的典型实践。










