How can I basically carry out a unique constraint on a string data-type field.
class User{
String username
String Email
static hasMany = [roles:Roles]
static constraints = {
Email(email:true)
username(unique:true)
}
}
Is there any simple way to implement username(unique: true)
Or must I manually check the database using methods like .findByNameLike
?
The username should be unique, but the uniqueness is should be case-insensitive.
So, if you want to have unique and case insensitive usernames, there are two possible approaches.
The simple one:
or, regarding performance, more expensive:
Now it depends, if you just want to give the user the freedom to enter his username in the case he wants (first possibility) or you want to keep the usernames case for displaying reasons (second possibility).
Your question sounds like the second one, so a custom validator would look like this:
class User {
String username
String email
static hasMany = [roles:Roles]
static constraints = {
email(email:true)
username(validator: {
return !User.findByUsernameILike(it)
})
}
}
Hope that helps.
[Edit]
As Heinrich states in his comment, the validator above will cause problems when users are able to change their username.
Quick & dirty, but I think this solves the issue:
username(validator: { val, obj ->
def similarUser = User.findByUsernameILike(val)
return !similarUser || obj.id == similarUser.id
})
Beware, it's not tested and I'm not sure if you're able to define variables in validators.
Meta: I would never let the users change their username ;)
In order to add another solution of the "quick and dirty" solution of @air_blob, did you try that ?
username(validator: { val, obj ->
return !User.findByUsernameIlikeAndIdNotEqual(val, obj.id)
})
username(unique:true)
is a valid constraint.
To make the constraint case insensitive you would need to write a custom validator. See this discussion thread for more information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With