2010-05-31 7 views
8

Tengo un modelo que tiene un amount y estoy rastreando para ver si este monto se cambia con un Model.amount_changed? con un before_save que funciona bien pero cuando reviso para ver amount_was y amount_change? solo devuelve el monto actualizado, no la cantidad anterior . Y todo esto está sucediendo antes de que sea guardado. Sabe cuándo se cambia el atributo, pero no devolverá el valor anterior.Rieles: attribute_changed?

Ideas?

class Reservation < ActiveRecord::Base 

before_save :status_amount, :if => :status_amount_changed 

def status_amount_changed 
    if self.amount_changed? && !self.new_record? 
    true 
    else 
    false 
    end 
end 

def status_amount 
    title = "Changed Amount" 
    description = "to #{self.amount_was} changed to #{self.amount} units" 
    create_reservation_event(title, description) 
end 

def create_reservation_event(title, description) 
    Event.create(:reservation => self, :sharedorder => self.sharedorder, :title => title,  :description => description, :retailer => self.retailer) 
end 

end 
+0

Se puede publicar el código de modelo? – microspino

+0

He añadido la parte correspondiente – s84

Respuesta

29

Si desea realizar un seguimiento de los cambios en sus rieles modelo proporciona "Dirty Objects". P. ej. Su modelo tiene un atributo name:

my_model = MyModel.find(:first) 
my_model.changed? # it returns false 

# You can Track changes to attributes with my_model.name_changed? accessor 
my_model.name # returns "Name" 
my_model.name = "New Name" 
my_model.name_changed? # returns true 

# Access previous value with name_was accessor 
my_model.name_was # "Name" 

# You can also see both the previous and the current values, using name_change 
my_model.name_change #=> ["Name", "New Name"] 

Si desea almacenar el valor antiguo dentro de su base de datos, puede utilizar:

  1. el modelo de atributos amount
  2. el método _was en el atributo anterior en otras palabras: amount_was que recupera el valor de cantidad antes del cambio.

Puede guardar ambos durante la llamada update_attributes. De lo contrario, si no necesita el historial amount_was, puede simplemente usar dos variables de instancia.

Si necesita algo más, como rastrear el historial de su modelo, Rails tiene un buen complemento dedicado. En cuanto a otros temas agradables hablan Ryan Bates sobre I here: Railscasts #177

+0

cantidad es el atributo, _was el método para encontrar el valor antes cambiado. Mismo método. Vi los railscasts. – s84

+0

@ s84 - En Rails 4 (no estoy seguro de 3), llamar al siguiente NO funcionaría: 'Person.first.city_id_was.state'. En cambio, debe hacer: 'City.find (Person.first.city_id_was) .state'. – onebree

0

Puede crear otro atributo vertual en su módulo

attr_accessor: initial_amount

y cuando se cargan datos de DB, llenar el initial_amount con la cantidad

entonces usted puede comprobar

(initial_amount cantidad == true: false)

aplausos, sameera

+0

cómo obtener el valor inicial – s84

3

Uso *_was llamada para obtener el valor antiguo:

p m.amount_was if m.amount_changed?