验证在唯一约束中失败

Posted

技术标签:

【中文标题】验证在唯一约束中失败【英文标题】:Validation fails in Unique constraint 【发布时间】:2015-05-08 17:19:26 【问题描述】:

我正在使用 Laravel 的 Validator 类验证一个简单的表单。

在我的用户模型中,我创建了这个函数来返回一个带有验证规则的数组:

/** function to return the rules to validate a user */
    public static function rules($email = null, $username = null) 
        return array(
            "name" => "required",
            "username" => "required|unique:user,username" . ($username ? ",'$username',username" : ""),
            "email" => "required|email|unique:user,email" . ($email ? ",'$email',email" : ""),
        );
    

我使用的是 RESTful 控制器,因此,当我执行 update() 方法时,我会使用上面的数组验证表单数据。

这是规则函数执行后我的数组:

array (size=3)
  'name' => string 'required' (length=8)
  'username' => string 'required|unique:user,username,'vitorluis',username' (length=50)
  'email' => string 'required|email|unique:user,email,'myemail@gmail.com',email' (length=63)

我告诉 Laravel 忽略这个电子邮件和用户名,但是验证器失败了,说给定的用户名和电子邮件已经存在。

我做错了什么?

【问题讨论】:

【参考方案1】:

您对unique 规则的id 参数有一点误解。您需要传入正在更新的记录的 id,然后告诉唯一规则排除该记录 id。

// $id should be the string 'NULL' if no id passed in
public static function rules($id = 'NULL') 
    return array(
        "name" => "required",
        "username" => "required|unique:user,username,".$id.",id_user",
        "email" => "required|email|unique:user,email,".$id.",id_user",
    );

说明

对于您现有的实现,如果您要查看查询日志 (DB::getQueryLog()),您会看到为您的名称验证运行的语句将是:

select count(*) as aggregate from `user` where `username` = 'vitorluis' and `username` <> '\'vitorluis\''

此查询将返回 1,表示找到一条记录并且新数据不是唯一的(唯一验证失败)。

如果您要通过引用传递给规则的值来解决一个问题,那么您的查询最终会是:

select count(*) as aggregate from `user` where `username` = 'vitorluis' and `username` <> 'vitorluis'

显然,此查询将始终返回 0,因此无论您将用户名更改为什么值,它都会始终通过唯一规则。

您真正想要做的是确保您分配的用户名对于每条记录都是唯一的,您当前正在更新的一条记录除外。为此,您将当前正在更新的记录的 id 传递给验证规则,以便它可以创建正确的查询。假设您正在更新 id 为 10 的记录:

select count(*) as aggregate from `user` where `username` = 'vitorluis' and `id_user` <> 10

编辑

由于 cmets 而编辑

如果id字段不是id,可以使用unique规则的第四个参数指定id字段。我已将上面的代码更新为使用您的 id 字段名称id_user

唯一规则的 Laravel 文档可以在 here 找到。

【讨论】:

对,帕特里克斯,但是,我的主键不是id,而是id_user。我怎么能在数组规则中这么说?我告诉你这个,因为 Laravel 抛出这个错误:Undefined column: 7 ERROR: column "id" does not exist @VitorLuis 如果您的主键与id 不同,您可以在 ID 值之后传递它。在这种情况下:"username" =&gt; "required|unique:user,username,".$id.",id_user".

以上是关于验证在唯一约束中失败的主要内容,如果未能解决你的问题,请参考以下文章

Django:异常类型:IntegrityError 唯一约束失败:auth_user.username

prisma ORM 错误:唯一约束在约束上失败:`Comment_postId_key`

唯一约束失败:sqlite 数据库:android

如何在 SQLiteConstraintException 上捕获列名唯一约束失败

Odoo中给字段填加唯一性约束

SQL - 添加唯一约束失败