I want to add a custom validator to a field in order to enforce a conditional non-null constraint. Since this requirement is shared across multiple objects, I want to reuse existing global (meaning not object- or field-specific) message keys. In the below example, I want to use default.null.message
and not something like objectA.fieldC.null.message
.
The documentation for the Grails validator seems to say that one can signal an error case by returning a string value that represents a key from message.properties. The documentation indicates (emphasis mine):
The closure can return:
- null or true (or no return value) 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.propertyName." 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 are used as formatted message arguments in the grails-app/i18n/message.properties file. The mapping of the arguments is as follows: Parameters 0 to 2 are automatically mapped to 0: property name, 1: class name, 2: property value. Additional parameters are mapped starting at parameter 3.
I've also found a Grails bug closed back in 1.0 that seems to request pretty much exactly what I am trying to do.
Here's an example of what I am doing. As you can see, I got one approach to work, but it really bugs me that the seemingly cleaner first two options do not work.
class ObjectA {
ObjectB fieldB
ObjectC fieldC
static constraints = {
fieldC(nullable: true, validator: { value, object, errors ->
if (object.fieldB != ObjectB.SOMETHING && !value) {
// Doesn't work
//return "default.null.message"
// Doesn't work
//return ["default.null.message"]
// This works
errors.rejectValue("defaultBrand", "default.null.message", ["defaultBrand"] as Object[], "The field \"{0}\" cannot be null")
}
})
}
}
Here's the entry in my message.properties
:
default.null.message=The field "{0}" cannot be null
I've seen a couple questions on here related to Grails custom field validators with custom error messages, but nothing seems to address my specific situation.