diff options
author | Sean Griffin <sean@thoughtbot.com> | 2014-12-22 14:55:58 -0700 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2014-12-22 14:55:58 -0700 |
commit | 18ae0656f527e790bdc827fe68e3f2edd541b3a4 (patch) | |
tree | 954a7fd17c2f88a322f7f9b4efac0eeb3b1d76ba /activemodel/lib/active_model/dirty.rb | |
parent | 849274316dc136135c50895e898e294904fec7a2 (diff) | |
download | rails-18ae0656f527e790bdc827fe68e3f2edd541b3a4.tar.gz rails-18ae0656f527e790bdc827fe68e3f2edd541b3a4.tar.bz2 rails-18ae0656f527e790bdc827fe68e3f2edd541b3a4.zip |
Don't calculate all in-place changes to determine if attribute_changed?
Calling `changed_attributes` will ultimately check if every mutable
attribute has changed in place. Since this gets called whenever an
attribute is assigned, it's extremely slow. Instead, we can avoid this
calculation until we actually need it.
Fixes #18029
Diffstat (limited to 'activemodel/lib/active_model/dirty.rb')
-rw-r--r-- | activemodel/lib/active_model/dirty.rb | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb index 60af31cca7..337b61c55c 100644 --- a/activemodel/lib/active_model/dirty.rb +++ b/activemodel/lib/active_model/dirty.rb @@ -170,7 +170,7 @@ module ActiveModel # Handle <tt>*_changed?</tt> for +method_missing+. def attribute_changed?(attr, options = {}) #:nodoc: - result = changed_attributes.include?(attr) + result = changes_include?(attr) result &&= options[:to] == __send__(attr) if options.key?(:to) result &&= options[:from] == changed_attributes[attr] if options.key?(:from) result @@ -188,6 +188,10 @@ module ActiveModel private + def changes_include?(attr_name) + attributes_changed_by_setter.include?(attr_name) + end + # Removes current changes and makes them accessible through +previous_changes+. def changes_applied # :doc: @previously_changed = changes |