#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.