I need to choose a set of validation rules at save time. Ideally I would like to be able to define more than one set of constraints in the domain class:
class Account {
...
static constraints = { ... }
static constraints2 = { ... }
}
I know I can do my own validation in code (account.errors.rejectValue(...) etc) but I am looking to save some time by using the built in Grails validation if possible.
This is what Command Objects are for.
The reason you can't just swap out validation is that the validation also helps define the database structure, like setting a field to be non-null, or non-blank, or having a specific length. Turning off "non-null", for example, could break the database structure.
Command objects, on the other hand, are designed to have their own unique set of validation rules. It's not the cleanest method (now you are tracking the same structure in more than one situation), but it's better in a lot of ways.
- It allows you to securely accept input parameters without worrying that something that shouldn't be processed gets set.
- It creates cleaner controllers, since the validation logic can all be handled within the Command Object, and not sprinkled through the controller method.
- They allow you to validate properties that don't actually exist on the object (such as password verification fields).
If you think you really need multiple sets of constraints, you are most likely either a) over-complicating the domain object to represent more information than it really should (maybe break it up into several one-to-one related objects), or b) incorrectly setting the constraints in the first place.†
In my experience, usually it's a that happens when you feel the need to swap out constraints.
† That being said, it can (rarely) make sense. But Command objects are the best solution in this situation.
you can use the validator constraint, see: http://www.grails.org/doc/latest/ref/Constraints/validator.html
within one validator constraint you can perform more checks than one and return diffrent error codes, e.g.
static constaints = {
name: validator { value, obj ->
if (value.size() > 10)
return [invalid.length]
else if (value.contains("test"))
return [invalid.content]
return true
}
in message.properties
domainClass.propName.invalid.content = ...
}