Search code examples
constraintsgrails-ormgrails

return domain objects from grails constraint validation


Is it possible to write your own validator in grails that will return a valid object?

Something like:

static constraints = {
    name(validator: {val, obj ->
        if (Drink.findByName(val)) return [Drink.findByName(val)]
    })
}

In other words - if the Drink already exists in the DB, just return the existing one when someone does a

new Drink("Coke")

and coke is already in the database


Solution

  • You cannot do this with a custom validator. It's not really what it was meant for. From the Grails Reference:

    The closure can return:

    • null or true to indicate that the value is valid
    • false to indicate an invalid value and use the default message code
    • a string to indicate the error code to append to the "classname.propertName." string used to resolve the error message. If a field specific message cannot be resolved, the error code itself will be resolved allowing for global error messages.
    • a list containing a string as above, and then any number of arguments following it, which can be used as formatted message arguments indexed at 3 onwards. See grails-app/i18n/message.properties to see how the default error message codes use the arguments.

    An alternative might be to just create a service method that 1) looks for the domain and returns it if it exists, 2) otherwise, saves the domain and returns it.

    There's probably a more elegant alternative. Regardless, Grails' constraints mechanism isn't (and shouldn't be) capable of this.