aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib/active_model/dirty.rb
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2014-12-22 14:55:58 -0700
committerSean Griffin <sean@thoughtbot.com>2014-12-22 14:55:58 -0700
commit18ae0656f527e790bdc827fe68e3f2edd541b3a4 (patch)
tree954a7fd17c2f88a322f7f9b4efac0eeb3b1d76ba /activemodel/lib/active_model/dirty.rb
parent849274316dc136135c50895e898e294904fec7a2 (diff)
downloadrails-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.rb6
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