class User {
String userId
String password
String password2
String email
static constraints = {
password(blank: false, nullable: false, size:5..20, validator: {password, obj ->
def password2 = obj.properties['password2']
if(password2 == null) return true // skip matching password validation (only important when setting/resetting pass)
password2 == password ? true : ['invalid.matchingpasswords']
})
}
static transients = ['password2']
}
Notice password2 property is a 'transient' property. This means it will not be included in the database model or object relational mapping of GORM. The other trick here is the custom validator closure in the constraints for the password field. The way this validator works is if password2 property is not null compare it with password, if they do not equal return the error code 'invalid.matchingpasswords'.
In this case you could add the error code user.password.invalid.matchingpasswords in the messages.properties file in 'grails-app/i18n' folder of your project. Do this like normal Java properties:
user.password.invalid.matchingpasswords=uh oh the passwords you entered do not match
Now in cases where password2 is not being used it will be null. This will prevent the validator from doing the test of password vs. password2. This is important if you have forms which update the other fields on your user class while not updating the password field. With out this check for null you would have many troubles saving user instances due to this validation. Note this trick it could be useful to you many times over!
To finish this little exercise off check out this little bit of controller code:
class UsersController {
def create = {
// maybe pass some models into template?
}
def save = {
def user = new User(params) // password, password2 set from form?
if(user.save())
{
flash.message = "user '${user.userId}' added"
redirect(action:create)
}
else
{
flash.message = "error(s) creating user"
render(view:"create",model:[user:user])
}
}
}
When creating the new User object we pass params to the constructor. This will cause the form parameters to bind to the User object's properties. See the data binding section of the Grails reference documentation. If password2 was a form field then it is auto magically set on the new User object. When we call save a few lines later this value will be compared with the 'password' property, voila!