Grails: могу ли я применить валидатор только для создания (не обновлять / редактировать)
У меня есть класс домена, который должен иметь дату после дня его создания в одном из его полей.
class myClass {
Date startDate
String iAmGonnaChangeThisInSeveralDays
static constraints = {
iAmGonnaChangeThisInSeveralDays(nullable:true)
startDate(validator:{
def now = new Date()
def roundedDay = DateUtils.round(now, Calendar.DATE)
def checkAgainst
if(roundedDay>now){
Calendar cal = Calendar.getInstance();
cal.setTime(roundedDay);
cal.add(Calendar.DAY_OF_YEAR, -1); // <--
checkAgainst = cal.getTime();
}
else checkAgainst = roundedDay
return (it >= checkAgainst)
})
}
}
Таким образом, несколько дней спустя, когда я изменяю только строку и вызываю save, сохранение завершается неудачно, потому что валидатор перепроверяет дату, и теперь она в прошлом. Могу ли я установить валидатор так, чтобы он запускался только при создании, или есть какой-то способ изменить его, чтобы он определял, создаем ли мы или редактируем / обновляем?
@Rob H Я не совсем уверен, как использовать ваш ответ. У меня есть следующий код, вызывающий эту ошибку:
myInstance.iAmGonnaChangeThisInSeveralDays = "nachos"
myInstance.save()
if(myInstance.hasErrors()){
println "This keeps happening because of the stupid date problem"
}
2 ответа
Вы можете проверить, если id
устанавливается как индикатор того, является ли это новый непостоянный экземпляр или существующий постоянный экземпляр:
startDate(validator:{ date, obj ->
if (obj.id) {
// don't check existing instances
return
}
def now = new Date()
...
}
Одним из вариантов может быть указание, какие свойства вы хотите проверить. Из документации:
Метод validate принимает необязательный аргумент List, который может содержать имена свойств, которые должны быть проверены. Когда список передается в метод validate, будут проверяться только свойства, определенные в списке.
Пример:
// when saving for the first time:
myInstance.startDate = new Date()
if(myInstance.validate() && myInstance.save()) { ... }
// when updating later
myInstance.iAmGonnaChangeThisInSeveralDays = 'New Value'
myInstance.validate(['iAmGonnaChangeThisInSeveralDays'])
if(myInstance.hasErrors() || !myInstance.save(validate: false)) {
// handle errors
} else {
// handle success
}
Это кажется немного хакерским, так как вы обходите некое встроенное качество Grails. Вы должны быть осторожны, чтобы не пропустить необходимую проверку домена, которая обычно происходит, если вы просто позвоните save()
, Мне было бы интересно увидеть решения других, если есть более элегантные.
Примечание: я действительно не рекомендую использоватьsave(validate: false)
если вы можете избежать этого. Это неизбежно приведет к непредвиденным негативным последствиям в будущем, если вы не будете очень осторожны в том, как вы их используете. Если вы можете найти альтернативу, обязательно используйте ее.