Existing Groovy DSLs
[ 232 ]
Constraints
You will have noticed that every domain class produced by the grails create-
domain-class command contains an empty static closure, constraints. We can
use this closure to set the constraints on any field in our model. Here, we apply
constraints to the e-mail and password fields of Identity. We want an e-mail field
to be unique, not blank, and not nullable. The password field should be 6 to 200
characters long, not blank, and not nullable:
class Identity {
String email
String password
static constraints = {
email(unique: true, blank: false, nullable: false)
password(blank: false, nullable:false, size:6..200)
}
}
From our knowledge of builders and the markup pattern, we can see that GORM
could be using a similar strategy here to apply constraints to the domain class. It
looks like a pretended method is provided for each field in the class that accepts a
map as an argument. The map entries are interpreted as constraints to apply to the
model field.
The builder pattern turns out to be a good guess as to how GORM is implementing
this. GORM actually implements constraints through a builder class called
ConstrainedPropertyBuilder. The closure that gets assigned to constraints
is in fact some markup style closure code for this builder. Before executing the
constraints closure, GORM sets an instance of ConstrainedPropertyBuilder
to be the delegate for the closure. We are more accustomed to seeing builder code
where the Builder instance is visible:
def builder = new ConstrainedPropertyBuilder()
builder.constraints {
}
Setting the builder as a delegate of any closure allows us to execute the closure as if it
was coded in the previous style. The constraints closure can be run at any time by
Grails, and as it executes ConstrainedPropertyBuilder, it will build a HashMap of
the constraints it encounters for each field.
http://www.ebook3000.com