我正在使用grails 2.2.1并尝试验证嵌套的命令结构。这是我的命令对象的简化版本:
@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()
}
}
}
当我尝试验证SurveyCommand
的实例时,无论部分值如何,它总是返回true
,并且SectionCommand
(answerNotBlank
)中的自定义验证器永远不会被调用。从grails文档中,似乎this kind of nested structure is supported(deepValidate
默认为true)。但是,这个规则可能只适用于域对象而不适用于Command对象?或者我在这里错过了什么?
答案 0 :(得分:5)
对于Grails 2.3及更高版本,我发现Cascade Validation Plugin很好地解决了这个问题。它定义了一个名为cascade的新验证器类型,它完全符合您的期望。安装完成后,您的示例将变为:
class SurveyCommand {
...
static constraints = {
useful(cascade: true)
recommend(cascade: true)
}
}
答案 1 :(得分:4)
您可以将自定义验证程序添加到主命令对象
@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 :(得分:2)
如果您尝试使用validation
从unit
测试中测试mockForConstraintsTest()
,那么您应该在command
中注册Config.groovy
个对象,而不是使用{{1}因为现有的Grails Bug。有关详细信息,请参阅此SO question/answers。
您可以在@Validateable
Config.groovy