geofflane/grails-constraints — pull request #14 by samcday (2012-01-25 14:09:04+00:00)
Title: Veto support for constraints

Hi Geoff,

One more pull request for you, this will probably be the last one for now!

This patch gives constraints the ability to **veto** any further constraints from validating a field. This concept is something that isn't actually possible in standard Grails custom validators (to my knowledge), but does exist and is used in the grails core - primarily for things like the nullable constraint.

If you're wondering where something like vetoing might be handy, consider this:

class Foo {
String date

static constraints = {
date(validDate: true, validation: { val ->
// Some code to make sure the date is in
// the future, or something.
}
}
}

// ...

class ValidDateConstraint {
static vetoer = true

def validate = { val ->
if(!parseDate(val)) {
veto = true
return false
}
}
}

As you can see, the ValidDateConstraint has indicated that it wishes to be able to veto subsequent constraints, and has exercised that veto power when it determines that a date isn't valid. This means that the custom validation written in Foo constraints will not execute *at all* unless a valid date has been provided. Without vetoing, if a user were to provide an invalid date, they would receive two errors, one for the fact that they have an invalid date, and another stating that the (not yet valid) date is not in the future.

I feel that exposing veto capabilities to Constraints makes them much more composable, you could have a group of custom validations that run against a single field and work well together. Of course, sometimes it might make sense to present multiple validation fails on a single field, if the errors are pertinent enough. Veto support just gives developers the flexibility to decide that for themselves.

The code is commented and has a test written for it. Let me know if you need anything else, or want to discuss this concept further.