2011-05-09 7 views
6

Tengo una clase de dominio que necesita tener una fecha posterior al día en que se creó en uno de sus campos.Grails: puedo hacer que un validador se aplique solo para crear (no actualizar/editar)

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

Así varios días después cuando cambio solamente la cuerda y llamo a salvar falla el proceso de almacenamiento debido a que el validador está volviendo a comprobar la fecha y ahora está en el pasado. ¿Puedo configurar el validador para que se active solo en la creación, o hay alguna forma de que pueda cambiarlo para detectar si estamos creando o editando/actualizando?

@Rob H No estoy del todo seguro de cómo usar su respuesta. Tengo el siguiente código que causa este error:

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

será nunca el caso de que 'startDate' se actualiza después de la guardar inicial? –

+0

Nunca debe cambiarse. – Mikey

Respuesta

12

Puede comprobar si el id se fija como un indicador de si se trata de una nueva instancia no persistente o una instancia persistente existente:

startDate(validator:{ date, obj -> 
    if (obj.id) { 
     // don't check existing instances 
     return 
    } 
    def now = new Date() 
    ... 
} 
+0

Esto es exactamente lo que necesitaba + un truco bastante agradable. – Mikey

0

Una opción podría ser especificar qué propiedades desea validar. Desde el documentation:

The validate method accepts an optional List argument which may contain the names of the properties that should be validated. When a List is passed to the validate method, only the properties defined in the List will be validated.

Ejemplo:

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

Esto se siente un poco hacky, ya que estás pasando por alto algo de bondad Griales incorporado. Deberá tener cuidado de no omitir ninguna validación necesaria en el dominio que normalmente ocurriría si tuviera que llamar al save(). Me interesaría ver las soluciones de otros si hay más elegantes.

Nota: Realmente no recomendamos el uso save(validate: false) si puede evitarlo. Seguramente causará algunas consecuencias negativas imprevistas en el camino a menos que tenga mucho cuidado con la forma de usarlo. Si puedes encontrar una alternativa, úsala en su lugar.

+0

No estoy del todo seguro de cómo usar esto; por favor vea mi edición a mi pregunta original. – Mikey

+1

@Mikey: actualicé mi respuesta. Necesito hacer una prueba rápida para asegurarme de que esté bien. Si no, se puede actualizar para usar 'save (validate: false)' para evitar que Grails invoque 'validate()' una vez que ya lo haya hecho usted mismo. –

+0

@Mikey - Hizo otra actualización después de hacer algunas pruebas. Tal vez te funcione. –

Cuestiones relacionadas