Search code examples
validationgrailsgroovygrails-orm

In a Grails domain object, is it possible to validate a field based on another field?


I have a Grails domain object that looks like this:

class Product {
    Boolean isDiscounted = false
    Integer discountPercent = 0

    static constraints = {
        isDiscounted(nullable: false)
        discountPercent(range:0..99)
}

I'd like to add a validator to discountPercent that will only validate if isDiscounted is true, something like this:

validator: { val, thisProduct ->
    if (thisProduct.isDiscounted) {
        // need to run the default validator here
        thisProduct.discountPercent.validate() // not actual working code
    } else {
        thisProduct.discountPercent = null // reset discount percent
}

Does anyone know how I can do this?


Solution

  • This is more or less what you need (on the discountPercent field):

    validator: { val, thisProduct ->
    if (thisProduct.isDiscounted)
        if (val < 0) {
            return 'range.toosmall' //default code for this range constraint error
        }
        if (99 < val) {
            return 'range.toobig' //default code for this range constraint error
    
    } else {
        return 'invalid.dependency'
    }
    

    You can't both have a special validator that relies on something else and have a special validator, as you can't run a single validator on a field (that I know of), only on single properties. But if you run a validation on this property, you'll depend on yourself and go into endless recursion. Therefore I added the range check manually. In your i18n files you can set up something like full.packet.path.FullClassName.invalid.dependency=Product not discounted.

    Good luck!