How to get the original value of an attribute in Rails

Ruby on-RailsActiverecord

Ruby on-Rails Problem Overview


is there a way to get the original value that an ActiveRecord attribute (=the value that was loaded from the database)?

I want something like this in an observer

before_save object
  do_something_with object.original_name
end

The task is to remove the object from a hash table (in fact, move it to another key in the table) upon updating.

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

Before rails 5.1

Appending _was to your attribute will give you the previous value.

For rails 5.1+

Copied from Lucas Andrade's answer below: https://stackoverflow.com/a/50973808/9359123


Appending _was is deprecated in rails 5.1, now you should append _before_last_save

Something like:

before_save object
  do_something_with object.name_before_last_save
end

Will return the name value before your last save at database (works for save and create)


The difference between _was and _before_last_save according to the documentation:

_was source from docs

def attribute_was(attr)
  attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
end

_before_last_save source from docs

def attribute_before_last_save(attr_name)
  mutations_before_last_save.original_value(attr_name)
end

Solution 2 - Ruby on-Rails

For rails 5.1+

Appending _was is deprecated in rails 5.1, now you should append _before_last_save

Something like:

before_save object
  do_something_with object.name_before_last_save
end

Will return the name value before your last save at database (works for save and create)


The difference between _was and _before_last_save according to the documentation:

_was source from docs

def attribute_was(attr)
  attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
end

_before_last_save source from docs

def attribute_before_last_save(attr_name)
  mutations_before_last_save.original_value(attr_name)
end

You can see a better example here

Solution 3 - Ruby on-Rails

ActiveRecord's attributes_before_type_cast method returns a hash of attributes before typecasting and deserialization have occurred.

Solution 4 - Ruby on-Rails

Take a look in rails documentation

http://api.rubyonrails.org/classes/ActiveModel/Dirty.html

Model.attribute_was return previous value :D

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLeonid ShevtsovView Question on Stackoverflow
Solution 1 - Ruby on-RailsVincentView Answer on Stackoverflow
Solution 2 - Ruby on-RailsLucas AndradeView Answer on Stackoverflow
Solution 3 - Ruby on-RailsJohn TopleyView Answer on Stackoverflow
Solution 4 - Ruby on-Railsrderoldan1View Answer on Stackoverflow