2011-04-10 126 views
7

通常,对于Grails域或命令类,您声明了约束,并且框架添加了一个validate()方法,用于检查每个约束是否对当前实例有效,例如,自定义Grails验证

class Adult { 

    String name 
    Integer age 

    void preValidate() { 
    // Implementation omitted 
    } 

    static constraints = { 
    name(blank: false) 
    age(min: 18) 
    } 
} 

def p = new Person(name: 'bob', age: 21) 
p.validate() 

在我的情况下,我想确保preValidate始终在类验证之前执行。我可以通过添加一个方法

def customValidate() { 
    preValidate() 
    validate() 
} 

但后来大家谁使用这个类需要记住实现这个调用customValidate而不是validate。我不能做到这一点无论

def validate() { 
    preValidate() 
    super.validate() 
} 

因为validate不是父类的方法(它是由元编程添加)。有另一种方法来实现我的目标吗?

回答

2

当你的域名/命令类有一个preValidate()方法时,你应该能够通过在元类上使用你自己的验证版本来实现这一点。类似于下面的代码的东西在你的BootStrap.groovy可以为你工作:

class BootStrap { 

    def grailsApplication // Set via dependency injection 

    def init = { servletContext -> 

     for (artefactClass in grailsApplication.allArtefacts) { 
      def origValidate = artefactClass.metaClass.getMetaMethod('validate', [] as Class[]) 
      if (!origValidate) { 
       continue 
      } 

      def preValidateMethod = artefactClass.metaClass.getMetaMethod('preValidate', [] as Class[]) 
      if (!preValidateMethod) { 
       continue 
      } 

      artefactClass.metaClass.validate = { 
       preValidateMethod.invoke(delegate) 
       origValidate.invoke(delegate) 
      } 
     } 
    } 

    def destroy = { 
    } 
} 
2

您可以完成使用beforeValidate()事件你的目标。它在1.3.6 Release Notes中有描述。