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

时间:2010-03-29 12:30:22

标签: grails gorm

我如何基本上对字符串数据类型字段执行唯一约束。

class User{
  String username
  String Email

  static hasMany = [roles:Roles]

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

    }
}

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

或者我必须使用.findByNameLike等方法手动检查数据库吗?

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

3 个答案:

答案 0 :(得分:13)

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

简单的一个:

  • 将它们存放在大写或小写中,并使用唯一约束。

或者,关于性能,更贵:

  • 以混合大小写形式存储它们并使用custom validator,它通过比较不区分大小写的给定和现有用户名来检查数据库。

现在取决于,如果您只是想让用户自由地输入他想要的用户名(第一种可能性),或者您想保留用户名案例以显示原因(第二种可能性)。

你的问题听起来像是第二个,所以自定义验证器看起来像这样:

class User { 
  String username 
  String email

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

希望有所帮助。

[编辑]

正如海因里希在评论中所述,上述验证器会在用户更改用户名时出现问题。

快速&很脏,但我认为这解决了这个问题:

username(validator: { val, obj ->
                      def similarUser = User.findByUsernameILike(val) 
                      return !similarUser || obj.id == similarUser.id
                    })

注意,它没有经过测试,我不确定你是否能够在验证器中定义变量。

Meta:我绝不会让用户更改用户名;)

答案 1 :(得分:2)

为了添加@air_blob“快速而肮脏”的解决方案的另一个解决方案,你试过吗?

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

答案 2 :(得分:1)

username(unique:true)是一个有效的约束。

要使约束不区分大小写,您需要编写自定义验证程序。有关详细信息,请参阅this discussion thread