Grails: могу ли я применить валидатор только для создания (не обновлять / редактировать) - PullRequest
7 голосов
/ 10 мая 2011

У меня есть класс домена, в котором должна быть дата после дня его создания в одном из его полей.

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

Итак, через несколько дней, когда я изменяю только строку и вызываю, сохраняются сохранения.не удается, потому что валидатор перепроверяет дату, и теперь она в прошлом.Могу ли я установить валидатор на запуск только при создании, или есть какой-то способ изменить его, чтобы он определял, создаем ли мы или редактируем / обновляем?

@ Rob H Я не совсем уверен, как использовать ваш ответ.У меня есть следующий код, вызывающий эту ошибку:

myInstance.iAmGonnaChangeThisInSeveralDays = "nachos"
myInstance.save()
if(myInstance.hasErrors()){
  println "This keeps happening because of the stupid date problem"
}

Ответы [ 2 ]

13 голосов
/ 10 мая 2011

Вы можете проверить, установлен ли id как индикатор того, является ли этот новый непостоянный экземпляр или существующим постоянным экземпляром:

startDate(validator:{ date, obj ->
   if (obj.id) {
      // don't check existing instances
      return
   }
   def now = new Date()
   ...
}
0 голосов
/ 10 мая 2011

Один из вариантов может указывать, какие свойства вы хотите проверить. Из документации :

Метод 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
}

Это кажется немного хакерским, так как вы обходите некое встроенное добро Грааля. Вы должны быть осторожны, чтобы не пропустить необходимую проверку домена, которая обычно происходит, если вы просто позвоните save(). Мне было бы интересно посмотреть на решения других, если есть более элегантные.

Примечание: Я действительно не рекомендую использовать save(validate: false), если вы можете избежать этого. Это неизбежно приведет к непредвиденным негативным последствиям в будущем, если вы не будете очень осторожны в том, как вы их используете. Если вы можете найти альтернативу, во что бы то ни стало используйте ее.

...