2013-04-24 8 views
5

Sto utilizzando Grails 2.2.1 e sto tentando di convalidare una struttura di comando nidificata. Ecco una versione semplificata dei miei oggetti comando:grails validate oggetto comando nidificato non funzionante

@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() 
     } 
    } 
} 

Quando provo di convalidare un'istanza SurveyCommand restituisce sempre true non importa i valori di sezione e il mio validatore personalizzato in SectionCommand (answerNotBlank) non viene mai chiamato. Dalla documentazione Grails, sembra che this kind of nested structure is supported (deepValidate predefinito su true). Tuttavia, forse questa regola si applica solo agli oggetti dominio e non agli oggetti Command? O mi manca qualcosa qui?

risposta

4

Si potrebbe aggiungere un validatore personalizzato per l'oggetto di comando principale

@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

bello! funziona alla grande, tuttavia c'è un modo più SECCO invece di definire esplicitamente un vincolo per ogni sotto proprietà? –

2

Se si sta tentando di testare validation da unit test utilizzando mockForConstraintsTest() allora si dovrebbe registrare i command oggetti in Config.groovy invece di utilizzare @Validateable a causa di un esistente Grails Bug. Fare riferimento a questo SO question/answers per i dettagli.

È possibile registrare la classe validateable come di seguito nella Config.groovy

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

sembra * funzionare correttamente (in 2.2.1) per testare un metodo '.validate()' della classe di comando '@ Validatable' semplicemente chiamando' mockCommandObject' prima di istanziarlo, ad es. 'mockCommandObject SurveyCommand' –

+0

Accetto. Questo è stato il mio approccio alla domanda/risposta SO che ho menzionato prima. 'mockCommandObject' funziona ma' mockForConstraintsTest' ha esito negativo. – dmahapatro

+0

ah, capito, grazie per il chiarimento. Ovviamente non ho letto abbastanza vicino –

5

Per Grails 2.3 e poi ho scoperto che il Cascade Validation Plugin risolve questo problema bene. Definisce un nuovo tipo di validatore chiamato cascade che fa esattamente quello che ti aspetteresti. Una volta installato, il tuo esempio diventerebbe:

class SurveyCommand { 
    ... 

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