пользовательская проверка Grails

#grails #groovy #grails-validation

#grails #groovy #grails-проверка

Вопрос:

Обычно для домена Grails или командного класса вы объявляете свои ограничения, и платформа добавляет validate() метод, который проверяет, является ли каждое из этих ограничений допустимым для текущего экземпляра, например

 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 это не метод родительского класса (он добавлен с помощью метапрограммирования). Есть ли другой способ достичь моей цели?

Ответ №1:

Вы должны быть в состоянии выполнить это, используя свою собственную версию validate в метаклассе, когда ваш доменный / командный класс имеет метод 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.