diff options
author | eileencodes <eileencodes@gmail.com> | 2014-11-11 14:10:42 -0500 |
---|---|---|
committer | eileencodes <eileencodes@gmail.com> | 2015-01-02 17:15:30 -0500 |
commit | 5b0b3cce5c0ecef02f1f6f09aea1de44b9ca88cf (patch) | |
tree | 9a1832390c142580567ef65f1949276e00c45596 | |
parent | 092171da306609127dc50e7f45edadf4b27bc65d (diff) | |
download | rails-5b0b3cce5c0ecef02f1f6f09aea1de44b9ca88cf.tar.gz rails-5b0b3cce5c0ecef02f1f6f09aea1de44b9ca88cf.tar.bz2 rails-5b0b3cce5c0ecef02f1f6f09aea1de44b9ca88cf.zip |
Move `#alias_name` to `ReflectionProxy` class
Putting the `#alias_name` into ReflectionProxy means we don't have to
cache the `#alias_name` globally anymore - it's not cached per query.
-rw-r--r-- | activerecord/lib/active_record/associations/association_scope.rb | 33 | ||||
-rw-r--r-- | activerecord/lib/active_record/reflection.rb | 10 |
2 files changed, 23 insertions, 20 deletions
diff --git a/activerecord/lib/active_record/associations/association_scope.rb b/activerecord/lib/active_record/associations/association_scope.rb index b5a6954554..48288496c4 100644 --- a/activerecord/lib/active_record/associations/association_scope.rb +++ b/activerecord/lib/active_record/associations/association_scope.rb @@ -159,32 +159,45 @@ module ActiveRecord end def alias_name(name, alias_tracker) - alias_name = "#{plural_name}_#{name}_join" - table_name = klass.table_name - alias_tracker.aliased_table_for(table_name, alias_name) + @alias ||= begin + alias_name = "#{plural_name}_#{name}_join" + table_name = klass.table_name + alias_tracker.aliased_table_for(table_name, alias_name) + end + end + end + + class ReflectionProxy < SimpleDelegator + def alias_name(name, alias_tracker) + @alias ||= begin + alias_name = "#{plural_name}_#{name}" + alias_tracker.aliased_table_for(table_name, alias_name) + end end end def get_chain(reflection, association) - chain = reflection.chain.dup + chain = reflection.chain.map { |reflection| + ReflectionProxy.new(reflection) + } chain[0] = RuntimeReflection.new(reflection, association) chain end def add_constraints(scope, owner, assoc_klass, refl, tracker, chain) - tables = construct_tables(chain, tracker, refl.name) - + construct_tables(chain, tracker, refl.name) owner_reflection = chain.last - table = tables.last - scope = last_chain_scope(scope, table, owner_reflection, owner, connection, assoc_klass) + table = owner_reflection.alias_name(refl.name, tracker) + scope = last_chain_scope(scope, table, owner_reflection, owner, tracker, assoc_klass) # chain.first always == refl chain.each_with_index do |reflection, i| - table, foreign_table = tables.shift, tables.first + table = reflection.alias_name(refl.name, tracker) unless reflection == chain.last next_reflection = chain[i + 1] - scope = next_chain_scope(scope, table, reflection, connection, assoc_klass, foreign_table, next_reflection) + foreign_table = next_reflection.alias_name(refl.name, tracker) + scope = next_chain_scope(scope, table, reflection, tracker, assoc_klass, foreign_table, next_reflection) end # Exclude the scope of the association itself, because that diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 83771bd5dc..1bc92b1587 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -165,11 +165,6 @@ module ActiveRecord def constraints scope ? [scope] : [] end - - def alias_name(name, alias_tracker) - alias_name = "#{plural_name}_#{name}" - alias_tracker.aliased_table_for(table_name, alias_name) - end end # Base class for AggregateReflection and AssociationReflection. Objects of @@ -758,11 +753,6 @@ module ActiveRecord source_type = @prev_reflection.options[:source_type] lambda { |object| where(type => source_type) } end - - def alias_name(name, alias_tracker) - alias_name = "#{plural_name}_#{name}" - alias_tracker.aliased_table_for(table_name, alias_name) - end end # Consider the following example: |