2012-08-02 11 views
9

Estoy tratando de establecer un campo booleano en falso en función del valor de otro campo booleano. Intenté lo siguiente con un modelo ActiveRecord:Rieles: cómo usar before_save para cambiar un valor de campo basado en otro campo?

before_save :reconcile_xvent 

    def reconcile_xvent 
    self.xvent_hood = false if !self.xvent_plenum? 
    end 

Pero esto no funciona. Ahora, muchos de mis pruebas de unidad con fallan:

ActiveRecord::RecordNotSaved: ActiveRecord::RecordNotSaved 

¿Cómo puedo configurar xvent_hood ser falsa si xvent_plenum es falsa?

actualización

Aquí es lo que funciona (algunos de los cuales proviene de los comentarios/respuestas a continuación):

before_validation :reconcile_xvent 

def reconcile_xvent 
    if self.xvent_hood? 
    self.xvent_hood = false unless xvent_plenum? 
    end 
end 

no pude averiguar para hacer que funcione sin el "si mismo. xvent_hood? " parte ....

+0

Si 'xvent_hood' tiene que ser igual' xvent_plenum', tal vez lo que debe hacer un 'xvent_hood = xvent_plenum'. – MurifoX

+0

Pero no siempre serán iguales. xvent_plenum debería poder ser verdadero y xvent_hood falso. – croceldon

+1

Intenta usar 'a menos' entonces. 'self.xvend_hood = falso a menos que self.xvent_plenum'. – MurifoX

Respuesta

11

before_save es solamente llamado después de la validación ha pasado. Lo que hay que hacer es mover reconcile_xvent hasta before_validation en lugar de before_save

Si se mantiene ese método en before_save lo que sucederá es que se cree que xvent_hood es nulo, si usted tiene una validación que comprueba la nulidad de xvent_hood lo hará fallar antes de que se llame al before_save. Lo cual probablemente explique por qué recibió el error RecordNotSaved.

Otra cosa a tener en cuenta es que si tiene una propiedad booleana, tampoco puede usar validate_presence_of. Ver http://alexanderwong.me/post/16084280769/rails-validate-presence-of-boolean-and-arrays-mongoid

+0

Parece que funciona, pero ¿por qué before_save piensa que xvent_hood es nulo? – croceldon

+0

no es que before_save piense que xvent_hood es nulo, creo que lo que sucedió es que no pasó la validación antes de que incluso se llame a before_save en primer lugar.(Asumiendo que si tiene las validaciones apropiadas en su lugar, que es la razón por la cual sus registros no se guardan) –

+0

sería genial ver aquí un enlace a la documentación de before_save. – botbot

16

Acabo de resolver este problema también, el problema con el primer bloque de código es que está asignando el valor xvent_hood a falso, que luego es devuelto por su método before_save.

según

devoluciones de llamada Cancelación de

Si un before_ * devolución de llamada devuelve falso, todas las devoluciones de llamada más tarde y la acción asociada se cancelan. Si una devolución de llamada after_ * devuelve falso, todas las devoluciones de llamada posteriores se cancelan. Las rellamadas generalmente se ejecutan en en el orden en que están definidas, a excepción de las devoluciones de llamadas definidas como métodos en el modelo, que se llaman últimos.

de http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

+0

Esta es la respuesta correcta PERO, ¿cómo se resuelve el problema? ¿Cómo se asigna un valor booleano a falso en una devolución de llamada before_save? – csi

+2

Para asignar un valor booleano a falso en su before_save, asegúrese de devolver explícitamente true al final de su devolución de llamada. Por ejemplo: 'def before_save (registro) my_false_bool = false retorno verdadera end' – lyallward

+0

Esa es la primera vez que he visto rubí se comportan de una manera desagradable debido a que la omisión de palabras clave regulares como de retorno. OMFG que está frustrando. – sakurashinken

Cuestiones relacionadas