/ RAILS

Rails changed behavior of attribute_changed in callbacks

Rails changed behavior of attribute_changed? in after and before callbacks. Older versions will throw deprecation warnings indicating which methods to use instead.

When working on Rails 5.1.5 project, a warning was thrown in rails server logs.

DEPRECATION WARNING: The behavior of attribute_changed? inside of after callbacks will be changing in the next version of Rails. The new return value will reflect the behavior of calling the method after save returned (e.g. the opposite of what it returns now). To maintain the current behavior, use saved_change_to_attribute? instead.

Upon digging, found out the change where the behavior of AR::Dirty inside callbacks was changed.

In a nutshell, if you have used *changed? something like,

name_changed?

If used in after_filter

It needs to be replaced with,

saved_change_to_attribute?(:name)
# OR
saved_change_to_name?

If used in before_filter

It needs to be replaced with,

will_save_change_to_attribute?(:name)
# OR
will_save_change_to_name?

More about the discussion on topic can be found on the pull request here.

Changes to dirty callbacks

Similarly, there are new methods available indicating dirty values on a object on ActiveRecord.

  • saved_changes? : Returns boolean indicating if attributes changed on object. (useful in before filter)
  • saved_changes : Hash of changes saved (useful in after filter)
  • has_changes_to_save? : Returns boolean indicating if record has changes to be saved (useful in before filter)
  • changes_to_save : Hash of changes to be saved
  • saved_change_to_attribute?(attr_name) : Return boolean indicating if changed value for attr_name was saved (useful in after filter)
  • saved_change_to_attribute(attr_name) : Returns an array with old and new value saved for attr_name (useful in after filter)

Reference

  • Pull Request - Deprecate the behavior of AR::Dirty inside of after_(create|update|save) callbacks
  • Pull request - The behavior of attribute_changed? inside of after callbacks will be changing