6

我正在使用 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它总是返回,并且我在( ) 中的自定义验证器永远不会被调用。从 grails 文档来看,似乎支持这种嵌套结构(默认为 true)。但是,也许这条规则只适用于域对象而不适用于命令对象?还是我只是在这里遗漏了什么?trueSectionCommandanswerNotBlankdeepValidate

4

3 回答 3

6

对于 Grails 2.3 及更高版本,我发现Cascade Validation Plugin很好地解决了这个问题。它定义了一个名为 cascade 的新验证器类型,它完全符合您的期望。安装后,您的示例将变为:

class SurveyCommand {
    ...

    static constraints = {
        useful(cascade: true)
        recommend(cascade: true)
    }
}
于 2015-01-18T22:43:02.343 回答
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)
    }
}
于 2013-04-24T02:41:58.417 回答
2

如果您尝试使用测试validation进行unit测试,mockForConstraintsTest()那么您应该注册command对象Config.groovy而不是使用@Validateable,因为现有的Grails Bug。有关详细信息,请参阅此SO 问题/答案

您可以在下面注册可验证的类Config.groovy

grails.validateable.classes = 
           [yourpackage.SurveyCommand, yourpackage.SectionCommand] 
于 2013-04-24T05:26:53.883 回答