1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Build the AttributeMutationTracker lazily

For reads, we never need to construct this object. The double `defined?`
check is to avoid errors in tests
This commit is contained in:
Sean Griffin 2015-10-02 09:35:30 -04:00
parent c80b114c45
commit ede244e236
2 changed files with 16 additions and 14 deletions

View file

@ -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

View file

@ -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?)