aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
authorSean Griffin <sean@seantheprogrammer.com>2015-10-02 09:35:30 -0400
committerSean Griffin <sean@seantheprogrammer.com>2015-10-02 09:37:31 -0400
commitede244e2367c7988fa02f5e3b956d88211bb5ade (patch)
tree0fc191c9a03d7684146a244bc0aecf20c44c3907 /activerecord/lib
parentc80b114c45215e713711c018a1ed2e6b264c22f8 (diff)
downloadrails-ede244e2367c7988fa02f5e3b956d88211bb5ade.tar.gz
rails-ede244e2367c7988fa02f5e3b956d88211bb5ade.tar.bz2
rails-ede244e2367c7988fa02f5e3b956d88211bb5ade.zip
Build the `AttributeMutationTracker` lazily
For reads, we never need to construct this object. The double `defined?` check is to avoid errors in tests
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/attribute_methods/dirty.rb28
-rw-r--r--activerecord/lib/active_record/persistence.rb2
2 files changed, 16 insertions, 14 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/dirty.rb b/activerecord/lib/active_record/attribute_methods/dirty.rb
index 17ec4c2252..e8a782ed13 100644
--- a/activerecord/lib/active_record/attribute_methods/dirty.rb
+++ b/activerecord/lib/active_record/attribute_methods/dirty.rb
@@ -35,27 +35,22 @@ module ActiveRecord
# <tt>reload</tt> the record and clears changed attributes.
def reload(*)
super.tap do
- @mutation_tracker = AttributeMutationTracker.new(@attributes)
+ @mutation_tracker = nil
@previous_mutation_tracker = nil
@changed_attributes = HashWithIndifferentAccess.new
end
end
- def init_internals
- super
- @mutation_tracker = AttributeMutationTracker.new(@attributes)
- end
-
def initialize_dup(other) # :nodoc:
super
@attributes = self.class._default_attributes.map do |attr|
attr.with_value_from_user(@attributes.fetch_value(attr.name))
end
- @mutation_tracker = AttributeMutationTracker.new(@attributes)
+ @mutation_tracker = nil
end
def changes_applied
- @previous_mutation_tracker = @mutation_tracker
+ @previous_mutation_tracker = mutation_tracker
@changed_attributes = HashWithIndifferentAccess.new
store_original_attributes
end
@@ -85,7 +80,7 @@ module ActiveRecord
if defined?(@cached_changed_attributes)
@cached_changed_attributes
else
- super.reverse_merge(@mutation_tracker.changed_values).freeze
+ super.reverse_merge(mutation_tracker.changed_values).freeze
end
end
@@ -100,17 +95,24 @@ module ActiveRecord
end
def attribute_changed_in_place?(attr_name)
- @mutation_tracker.changed_in_place?(attr_name)
+ mutation_tracker.changed_in_place?(attr_name)
end
private
+ def mutation_tracker
+ unless defined?(@mutation_tracker)
+ @mutation_tracker = nil
+ end
+ @mutation_tracker ||= AttributeMutationTracker.new(@attributes)
+ end
+
def changes_include?(attr_name)
- super || @mutation_tracker.changed?(attr_name)
+ super || mutation_tracker.changed?(attr_name)
end
def clear_attribute_change(attr_name)
- @mutation_tracker.forget_change(attr_name)
+ mutation_tracker.forget_change(attr_name)
end
def _update_record(*)
@@ -127,7 +129,7 @@ module ActiveRecord
def store_original_attributes
@attributes = @attributes.map(&:forgetting_assignment)
- @mutation_tracker = AttributeMutationTracker.new(@attributes)
+ @mutation_tracker = nil
end
def previous_mutation_tracker
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 7b53f6e5a0..3f02f73a5a 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -211,7 +211,7 @@ module ActiveRecord
def becomes(klass)
became = klass.new
became.instance_variable_set("@attributes", @attributes)
- became.instance_variable_set("@mutation_tracker", @mutation_tracker)
+ became.instance_variable_set("@mutation_tracker", @mutation_tracker) if defined?(@mutation_tracker)
became.instance_variable_set("@changed_attributes", attributes_changed_by_setter)
became.instance_variable_set("@new_record", new_record?)
became.instance_variable_set("@destroyed", destroyed?)