2010-05-31 5 views
8

Ich habe ein Modell, das eine amount und ich bin Tracking, um zu sehen ist, wenn dieser Betrag mit einem Model.amount_changed? mit einem before_save geändert wird, der gut arbeitet, aber wenn ich sehe, überprüfen zu amount_was und amount_change? es gibt nur den aktualisierten Betrag nicht die vorherige Menge . Und all das passiert, bevor es gerettet ist. Es weiß, wann das Attribut geändert wird, aber es gibt den alten Wert nicht zurück.Schienen: attribute_changed?

Ideen?

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

können Sie das Modell Code posten? – microspino

+0

Ich habe den relevanten Teil hinzugefügt – s84

Antwort

29

Wenn Sie den Überblick über Änderungen in Ihrem Modell Rails behalten möchten bietet "Dirty Objects". Zum Beispiel Ihr Modell verfügt über eine name Attribut:

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"] 

Wenn Sie den alten Wert in der Datenbank speichern möchten, können Sie verwenden:

  1. das Modell Attribut amount
  2. das Verfahren _was auf die über Attribut mit anderen Worten: amount_was, die den Wert Betrag vor der Änderung abrufen.

Sie können beide während des Aufrufs update_attributes speichern. Andernfalls, wenn Sie die Historie amount_was nicht benötigen, können Sie nur zwei Instanzvariablen verwenden.

Wenn Sie etwas mehr brauchen, wie das Verfolgen Ihrer Modellhistorie, hat Rails ein nettes dediziertes Plugin. Wie für andere schöne Themen Ryan Bates sprechen über I here: Railscasts #177

+0

Betrag ist das Attribut, _was ist die Methode, um den zuvor geänderten Wert zu finden. Gleiche Methode. Ich sah die Railscasts. – s84

+0

@ s84 - In Rails 4 (nicht sicher von 3) würde das Aufrufen des folgenden nicht funktionieren: 'Person.first.city_id_was.state'. Stattdessen müssen Sie Folgendes tun: 'City.find (Person.first.city_id_was) .state'. – onebree

0

Sie ein anderes vertual Attribut in Ihrem Modul

attr_accessor erstellen: initial_amount

und wenn Sie Daten von DB laden, füllen Sie den initial_amount mit Menge

dann können Sie überprüfen,

(initial_amount == Menge wahr: false)

prost, sameera

+0

Wie bekomme ich den Anfangswert? – s84

3

Verwenden *_was Anruf den alten Wert zu erhalten:

p m.amount_was if m.amount_changed? 
Verwandte Themen