Vor dem Update in Rails 3 muss überprüft werden, ob sich ein Attributblock geändert hat.
Straße1, Straße2, Stadt, Bundesland, Postleitzahl
Ich weiß, ich könnte so etwas gebrauchen
if @user.street1 != params[:user][:street1]
then do something....
end
Aber dieser Code wird WIRKLICH lang sein. Gibt es einen saubereren Weg?
Auf diese Weise habe ich das Problem gelöst, nach Änderungen in mehreren Attributen zu suchen.
Die
changed
Methode gibt ein Array der für dieses Objekt geänderten Attribute zurück.Beide
@user.changed
undattrs
sind Arrays, damit ich den Schnittpunkt erhalten kann (sieheary & other ary
Methode). Das Ergebnis der Schnittmenge ist ein Array. Wennany?
ich das Array aufrufe, werde ich wahr, wenn es mindestens eine Kreuzung gibt.Ebenfalls sehr nützlich ist, dass die
changed_attributes
Methode einen Hash der Attribute mit ihren ursprünglichen Werten undchanges
einen Hash der Attribute mit ihren ursprünglichen und neuen Werten (in einem Array) zurückgibt.Sie können APIDock überprüfen, für welche Versionen diese Methoden unterstützt werden.
http://apidock.com/rails/ActiveModel/Dirty
quelle
if attrs.any?{|attr| @user.send("#{attr}_changed?")}
Wenn ich überprüfen möchte, ob sich eines von mehreren verschiedenen Attributen geändert hat - Natürlich mache ich dies nur mit attrs, die ich selbst definiert habe, weil ich es nicht mag, Benutzerparameter in einesend
Methode zu werfen . ;)ActiveModel::Dirty
hat bei mir nicht funktioniert, weil@model.update_attributes()
die Änderungen versteckt waren. So habe ich Änderungen in einerupdate
Methode in einem Controller festgestellt :Wenn Sie versuchen, viele Attributänderungen zu erkennen, kann dies jedoch zu Problemen führen. Wahrscheinlich sollte das nicht in einem Controller gemacht werden, aber meh.
quelle
previous_changes
was auch standardmäßig verfügbar ist.#update_attributes
versteckt die Änderungen nicht. Der Datensatz wird gespeichert, sodass das Modell aktualisiert wird und keine Änderungen vorgenommen werden. Sie müssen das Feld im Modell ändern und prüfen,changed?
bevor Sie es speichern. dh. @ model.field = 'foo' oder@model.attributes = @model.attributes.merge(params[:model])
Für Rails 5.1+ Rückrufe
Ab Ruby on Rails 5.1 sind die Methoden
attribute_changed?
undattribute_was
ActiveRecord veraltetVerwenden Sie
saved_change_to_attribute?
anstelle vonattribute_changed?
Weitere Beispiele hier
quelle
Die obigen Antworten sind besser, aber aus Wissensgründen haben wir auch einen anderen Ansatz: Lässt den Spaltenwert 'Kategorie' für ein Objekt (@design) ändern.
Die .changes geben einen Hash mit dem Schlüssel als Spaltennamen und den Werten als Array mit zwei Werten [alter_Wert, neuer_Wert] für jede Spalte zurück. Zum Beispiel wird die Kategorie für oben von 'ABC' in 'XYZ' von @design geändert.
Für Referenzen ändern Sie in ROR
quelle