aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorJeremy Kemper <jeremykemper@gmail.com>2014-08-25 20:59:47 -0700
committerJeremy Kemper <jeremykemper@gmail.com>2014-08-25 20:59:47 -0700
commit99a5333c9d77db816906dabd5ce7f0cb44197bc3 (patch)
tree494de2e2c389982ee17975307e263452a9e36be3 /activerecord
parent37939e28c953ab526c3fc9637f0239b095db1f70 (diff)
parent9384fa43cc7bbb32a2683821eaa9383344f03ebd (diff)
downloadrails-99a5333c9d77db816906dabd5ce7f0cb44197bc3.tar.gz
rails-99a5333c9d77db816906dabd5ce7f0cb44197bc3.tar.bz2
rails-99a5333c9d77db816906dabd5ce7f0cb44197bc3.zip
Merge pull request #16646 from sgrif/sg-perf-regression
Cache the value of `changed_attributes` when calling `changes_applied`
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/attribute_methods/dirty.rb21
1 files changed, 20 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb
index 01f126f1b3..2f02738f6d 100644
--- a/activerecord/lib/active_record/attribute_methods/dirty.rb
+++ b/activerecord/lib/active_record/attribute_methods/dirty.rb
@@ -54,7 +54,19 @@ module ActiveRecord
end
def changed_attributes
- super.reverse_merge(attributes_changed_in_place).freeze
+ # This should only be set by methods which will call changed_attributes
+ # multiple times when it is known that the computed value cannot change.
+ if defined?(@cached_changed_attributes)
+ @cached_changed_attributes
+ else
+ super.reverse_merge(attributes_changed_in_place).freeze
+ end
+ end
+
+ def changes
+ cache_changed_attributes do
+ super
+ end
end
private
@@ -157,6 +169,13 @@ module ActiveRecord
store_original_raw_attribute(attr)
end
end
+
+ def cache_changed_attributes
+ @cached_changed_attributes = changed_attributes
+ yield
+ ensure
+ remove_instance_variable(:@cached_changed_attributes)
+ end
end
end
end