问题
I'm using grails 2.2.1 and attempting to validate a nested command structure. Here is a simplified version of my command objects:
@Validateable
class SurveyCommand {
SectionCommand useful
SectionCommand recommend
SurveyCommand() {
useful = new SectionCommand(
question: 'Did you find this useful?',
isRequired: true)
recommend = new SectionCommand(
question: 'Would you recommend to someone else?',
isRequired: false)
}
}
@Validateable
class SectionCommand {
String question
String answer
boolean isRequired
static constraints = {
answer(validator: answerNotBlank, nullable: true)
}
static answerNotBlank = { String val, SectionCommand obj ->
if(obj.isRequired) {
return val != null && !val.isEmpty()
}
}
}
When I try to validate an instance of SurveyCommand
it always returns true
no matter the section values and my custom validator in SectionCommand
(answerNotBlank
) is never called. From the grails documentation, it seems that this kind of nested structure is supported (deepValidate
defaults to true). However, maybe this rule only applies to domain objects and not Command objects? Or am I just missing something here?
回答1:
You could add a custom validator to your main command object
@Validateable
class SurveyCommand {
SectionCommand useful
SectionCommand recommend
static subValidator = {val, obj ->
return val.validate() ?: 'not.valid'
}
static constraints = {
useful(validator: subValidator)
recommend(validator: subValidator)
}
SurveyCommand() {
useful = new SectionCommand(
question: 'Did you find this useful?',
isRequired: true)
recommend = new SectionCommand(
question: 'Would you recommend to someone else?',
isRequired: false)
}
}
回答2:
For Grails 2.3 and later I've found that the Cascade Validation Plugin solves this problem nicely. It defines a new validator type called cascade which does exactly what you'd expect. Once installed your example would become:
class SurveyCommand {
...
static constraints = {
useful(cascade: true)
recommend(cascade: true)
}
}
回答3:
If you are trying to test validation
from unit
tests using mockForConstraintsTest()
then you should register the command
objects inConfig.groovy
instead of using @Validateable
because of an existing Grails Bug. Refer this SO question/answers for details.
You can register the validateable class as below in Config.groovy
grails.validateable.classes =
[yourpackage.SurveyCommand, yourpackage.SectionCommand]
来源:https://stackoverflow.com/questions/16181599/grails-validate-nested-command-object-not-working