Grails中不区分大小写的唯一约束

Grails中不区分大小写的唯一约束,grails,gorm,Grails,Gorm,如何在字符串数据类型字段上执行唯一约束 class User{ String username String Email static hasMany = [roles:Roles] static constraints = { Email(email:true) username(unique:true) } } 有没有简单的方法来实现username(unique:true) 或者我必须使用.findByNameLike之类的方法手动

如何在字符串数据类型字段上执行唯一约束

class User{
  String username
  String Email

  static hasMany = [roles:Roles]

     static constraints = {
     Email(email:true)
     username(unique:true)

    }
}
有没有简单的方法来实现
username(unique:true)

或者我必须使用
.findByNameLike
之类的方法手动检查数据库吗


用户名应该是唯一的,但唯一性应该是不区分大小写的。

因此,如果您想拥有唯一且不区分大小写的用户名,有两种可能的方法

简单的一点是:

  • 将其存储为大写或小写,并使用唯一约束
或者,就性能而言,更昂贵:

  • 将它们存储在混合大小写中并使用,它通过比较给定用户名和现有用户名(不区分大小写)来检查数据库
现在这取决于,如果你只是想让用户自由输入他想要的用户名(第一种可能性),或者你想保留用户名的大小写以显示原因(第二种可能性)

您的问题听起来像第二个问题,因此自定义验证器如下所示:

class User { 
  String username 
  String email

  static hasMany = [roles:Roles]
  static constraints = {
    email(email:true)
    username(validator: {
              return !User.findByUsernameILike(it)
            })
  }
}
希望有帮助

[编辑]

正如Heinrich在评论中所说,当用户能够更改用户名时,上面的验证器将导致问题

快速和肮脏,但我认为这解决了问题:

username(validator: { val, obj ->
                      def similarUser = User.findByUsernameILike(val) 
                      return !similarUser || obj.id == similarUser.id
                    })
注意,它没有经过测试,我不确定您是否能够在验证器中定义变量

梅塔:我永远不会让用户更改他们的用户名;)

用户名(唯一:true)
是有效的约束


要使约束不区分大小写,您需要编写一个自定义验证器。有关更多信息,请参阅。

为了添加另一个@air\u blob的“快速脏”解决方案,您尝试过吗

username(validator: { val, obj ->
                      return !User.findByUsernameIlikeAndIdNotEqual(val, obj.id)                      
                    })

回答得好!我认为在更新“用户名”时,自定义验证器可能会出现问题。看见不知道,天哪!yes@Heinrich您是对的,当我尝试更新同一字段时,它确实失败了。用户名(验证器:{val,obj->def similarUser=User.findByUsernameILike(val)return!similarUser | |(obj.id==similarUser.id)})obj.id&&在条件中的用途是什么。我删除了它,它仍然可以正常工作。这只会检查实例是否有id。。。但是你是对的,obj.id==similarUser.id就足够了。编辑后,我不太擅长在没有测试的情况下从头开始编写坚如磐石的代码:)我宁愿编写一个验证程序,只检查用户名是否为小写-并且唯一,其余的将由它来处理。Mate,当我实现它时,我得到了以下错误:没有这样的属性:class:com.myCompany.userID链接返回404:(@Rafael我更新了链接,但我不确定这些信息是否仍然适用