2013-04-24 112 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) 
    } 
}