2013-04-24 152 views
5

我正在使用grails 2.2.1并尝试验证嵌套的命令结构。这是我的命令对象的一个​​简化版本:grails验证嵌套的命令对象不能正常工作

@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不管段值和SectionCommandanswerNotBlank)我自定义的验证永远不会被调用。从grails文档看来,this kind of nested structure is supporteddeepValidate默认为true)。但是,也许这个规则只适用于域对象而不是Command对象?或者我在这里错过了什么?

回答

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) 
    } 
} 
+0

不错!很好,但是有没有更明确的方式,而不是明确定义每个子属性的约束? – 2013-04-24 15:29:07

2

如果您尝试使用mockForConstraintsTest(),那么你应该在Config.groovy注册command对象来测试validationunit测试,而不是因为一个使用@Validateable现有的Grails Bug。详情请参考SO question/answers

可以在Config.groovy

grails.validateable.classes = 
      [yourpackage.SurveyCommand, yourpackage.SectionCommand] 
+0

通过在实例化它之前简单地调用mockCommandObject,它*看起来可以正常工作(在2.2.1中)来测试'@ Validatable'命令类的'.validate()'方法。 'mockCommandObject SurveyCommand' – 2013-04-24 15:26:19

+0

同意。那是我对前面提到的SO问题/答案的处理方法。 'mockCommandObject'工作,但'mockForConstraintsTest'失败。 – dmahapatro 2013-04-24 15:31:58

+0

啊,明白了,谢谢澄清。显然,我没有读得太近 – 2013-04-24 15:36:15

5

Grails的2.3注册为以下validateable类,后来我发现,Cascade Validation Plugin很好地解决了这个问题。它定义了一个名为级联的新验证器类型,它完全符合您的期望。一旦安装你的例子就会变成:

class SurveyCommand { 
    ... 

    static constraints = { 
     useful(cascade: true) 
     recommend(cascade: true) 
    } 
}