Merge pull request #16989 from Empact/reload-cache-clear

Isolate access to @associations_cache and @aggregations_cache to the Associations and Aggregations modules, respectively.
This commit is contained in:
Rafael Mendonça França 2015-02-20 17:45:10 -02:00
commit 37bef5827f
6 changed files with 53 additions and 28 deletions

@ -3,10 +3,27 @@ module ActiveRecord
module Aggregations # :nodoc:
extend ActiveSupport::Concern
def clear_aggregation_cache #:nodoc:
@aggregation_cache.clear if persisted?
def initialize_dup(*) # :nodoc:
@aggregation_cache = {}
super
end
def reload(*) # :nodoc:
clear_aggregation_cache
super
end
private
def clear_aggregation_cache # :nodoc:
@aggregation_cache.clear if persisted?
end
def init_internals # :nodoc:
@aggregation_cache = {}
super
end
# Active Record implements aggregation through a macro-like class method called +composed_of+
# for representing attributes as value objects. It expresses relationships like "Account [is]
# composed of Money [among other things]" or "Person [is] composed of [an] address". Each call
@ -89,7 +106,7 @@ def clear_aggregation_cache #:nodoc:
#
# customer.address_street = "Vesterbrogade"
# customer.address # => Address.new("Hyancintvej", "Copenhagen")
# customer.clear_aggregation_cache
# customer.send(:clear_aggregation_cache)
# customer.address # => Address.new("Vesterbrogade", "Copenhagen")
#
# customer.address = Address.new("May Street", "Chicago")

@ -145,20 +145,14 @@ module Builder #:nodoc:
autoload :AliasTracker, 'active_record/associations/alias_tracker'
end
# Clears out the association cache.
def clear_association_cache #:nodoc:
@association_cache.clear if persisted?
end
# :nodoc:
attr_reader :association_cache
# Returns the association instance for the given name, instantiating it if it doesn't already exist
def association(name) #:nodoc:
association = association_instance_get(name)
if association.nil?
raise AssociationNotFoundError.new(self, name) unless reflection = self.class._reflect_on_association(name)
unless reflection = self.class._reflect_on_association(name)
raise AssociationNotFoundError.new(self, name)
end
association = reflection.association_class.new(self, reflection)
association_instance_set(name, association)
end
@ -166,7 +160,31 @@ def association(name) #:nodoc:
association
end
def association_cached?(name) # :nodoc
@association_cache.key?(name)
end
def initialize_dup(*) # :nodoc:
@association_cache = {}
super
end
def reload(*) # :nodoc:
clear_association_cache
super
end
private
# Clears out the association cache.
def clear_association_cache # :nodoc:
@association_cache.clear if persisted?
end
def init_internals # :nodoc:
@association_cache = {}
super
end
# Returns the specified association instance if it responds to :loaded?, nil otherwise.
def association_instance_get(name)
@association_cache[name]

@ -239,12 +239,10 @@ def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
if node.reflection.collection?
other = ar_parent.association(node.reflection.name)
other.loaded!
else
if ar_parent.association_cache.key?(node.reflection.name)
model = ar_parent.association(node.reflection.name).target
construct(model, node, row, rs, seen, model_cache, aliases)
next
end
elsif ar_parent.association_cached?(node.reflection.name)
model = ar_parent.association(node.reflection.name).target
construct(model, node, row, rs, seen, model_cache, aliases)
next
end
key = aliases.column_alias(node, node.primary_key)

@ -345,9 +345,6 @@ def initialize_dup(other) # :nodoc:
_run_initialize_callbacks
@aggregation_cache = {}
@association_cache = {}
@new_record = true
@destroyed = false
@ -542,8 +539,6 @@ def to_ary # :nodoc:
end
def init_internals
@aggregation_cache = {}
@association_cache = {}
@readonly = false
@destroyed = false
@marked_for_destruction = false

@ -415,9 +415,6 @@ def toggle!(attribute)
# end
#
def reload(options = nil)
clear_aggregation_cache
clear_association_cache
fresh_object =
if options && options[:lock]
self.class.unscoped { self.class.lock(options[:lock]).find(id) }

@ -47,7 +47,7 @@ def test_clear_association_cache_stored
firm = Firm.find(1)
assert_kind_of Firm, firm
firm.clear_association_cache
firm.send(:clear_association_cache)
assert_equal Firm.find(1).clients.collect(&:name).sort, firm.clients.collect(&:name).sort
end
@ -61,7 +61,7 @@ def test_clear_association_cache_new_record
firm.clients << clients
assert_equal clients.map(&:name).to_set, firm.clients.map(&:name).to_set
firm.clear_association_cache
firm.send(:clear_association_cache)
assert_equal clients.map(&:name).to_set, firm.clients.map(&:name).to_set
end