Last updated by houbie 1 year ago
add the plugin to the plugins section in grails-app/conf/BuildConfig.groovy:
plugins {
runtime(':extended-validation:1.0.1')
…
}
Last updated by houbie 6 months ago
This plugin is deprecated. Use the rich-domain plugin instead.
Overview
The extended validation plugin adds validation capabilities to classes that are not grails domain classes.
The plugin is similar to the build-in
ValidationGrailsPlugin , but has a couple of extra features that make it particularly useful in combination with webflow:
- constraint groups
- cascaded validation
- instance validators
- partial validation
- errors that survive serialization/de-serialization
Usage
Making a class validateable
There are two ways to make a class validateable:
- Use the
be.ixor.grails.extendedvalidation.Validateable annotation
@Validateable
class Person {
…
static constraints = …
}
- Add the class to
grails.extendedvalidation.classes in Config.groovy
grails.extendedvalidation.classes = [Person, Address]
Classes that are listed in Config.groovy will not preserve errors after serialization / de-serialization.
This is because the Validateable annotation is linked with an ASTTransformation that adds an error id field to the class.
Defining constraints
In addition to the standard grails constraints, the plugin provides some extra features.
Constraint groups
You can define logical constraint groups. This is particularly useful in wizards, where the information comes from multiple pages and where one only wants to validate the fields on a certain page.
static constraints = {
personalDetails {
firstName(blank: false)
lastName(blank: false)
}
preferences {
uiPrefs(validator: {...})
}
}Cascaded validation
Validation of nested objects can be achieved with the
cascade constraint:
class Person {
…
Address address static constraints = {
address(cascade: true)
...Instance validation
Constraints that validate an instance rather than one field, don't need to be bound to a single field.
static constraints = {
maxNameLength(validator: {
if(firstName.size() + lastName.size() > 50) return "nameToLong"
})
...Partial validation
The dynamic
validate method accepts three arguments:
includes ,
excludes and
groups // check all constraints
person.validate()// only check included constraints
person.validate(includes: ["firstName", "lastName"])// exclude specific (cascaded) constraints
person.validate(excludes: ["firstName", "address.city"])// check only constraints in the specified groups, this will also limit cascaded validation to these groups
person.validate(groups: ["personalDetails"])// exclude the constraints in the specified groups (excludeGroups are cascaded)
person.validate(excludeGroups: ["personalDetails"])// all possible combinations are also valid: excludes are removed from the union of includes and groups
person.validate(includes: ["address.*", "curriculum.companies.*"], groups: ["personalDetails"], excludes: ["address.street"])
Nested errors
All errors can recursively be fetched and cleared :
assert person.allErrorsRecursive.size() == 3
person.clearErrorsRecursive()