From e8be3a9016b6c27ead6d5608c3f988c5f72b385b Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 30 Jan 2017 13:51:48 -0800 Subject: [PATCH] Fix `scopes` implementation on `PolymorphicReflection` `PolymorphicReflection` needs to be custom for handling scope lambdas --- .../associations/join_dependency.rb | 2 +- .../join_dependency/join_association.rb | 8 +-- activerecord/lib/active_record/reflection.rb | 59 ++++--------------- 3 files changed, 15 insertions(+), 54 deletions(-) diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb index a79eb03acc..87e0847ec1 100644 --- a/activerecord/lib/active_record/associations/join_dependency.rb +++ b/activerecord/lib/active_record/associations/join_dependency.rb @@ -171,7 +171,7 @@ def make_constraints(parent, child, tables, join_type) chain = child.reflection.chain foreign_table = parent.table foreign_klass = parent.base_klass - child.join_constraints(foreign_table, foreign_klass, child, join_type, tables, child.reflection.scope_chain, chain) + child.join_constraints(foreign_table, foreign_klass, child, join_type, tables, chain) end def make_outer_joins(parent, child) diff --git a/activerecord/lib/active_record/associations/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/join_dependency/join_association.rb index a5705951f3..f5fcba1236 100644 --- a/activerecord/lib/active_record/associations/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/join_dependency/join_association.rb @@ -23,14 +23,11 @@ def match?(other) JoinInformation = Struct.new :joins, :binds - def join_constraints(foreign_table, foreign_klass, node, join_type, tables, scope_chain, chain) + def join_constraints(foreign_table, foreign_klass, node, join_type, tables, chain) joins = [] binds = [] tables = tables.reverse - scope_chain_index = 0 - scope_chain = scope_chain.reverse - # The chain starts with the target table, but we want to end with it here (makes # more sense in this context), so we reverse chain.reverse_each do |reflection| @@ -44,7 +41,7 @@ def join_constraints(foreign_table, foreign_klass, node, join_type, tables, scop constraint = build_constraint(klass, table, key, foreign_table, foreign_key) predicate_builder = PredicateBuilder.new(TableMetadata.new(klass, table)) - scope_chain_items = scope_chain[scope_chain_index].map do |item| + scope_chain_items = reflection.scopes.map do |item| if item.is_a?(Relation) item else @@ -52,7 +49,6 @@ def join_constraints(foreign_table, foreign_klass, node, join_type, tables, scop .instance_exec(node, &item) end end - scope_chain_index += 1 klass_scope = if klass.current_scope diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index face8e9200..70e2487891 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -179,8 +179,12 @@ def scopes scope ? [scope] : [] end + def scope_chain + chain.map(&:scopes) + end + def constraints - scope_chain.flatten + chain.map(&:scopes).flatten end def counter_cache_column @@ -465,12 +469,6 @@ def nested? false end - # An array of arrays of scopes. Each item in the outside array corresponds to a reflection - # in the #chain. - def scope_chain - scope ? [[scope]] : [[]] - end - def has_scope? scope end @@ -820,30 +818,14 @@ def clear_association_scope_cache # :nodoc: # but only Comment.tags will be represented in the #chain. So this method creates an array # of scopes corresponding to the chain. def scopes - @sc ||= if scope - source_reflection.scopes + through_reflection.scopes + [scope] + if scope + source_reflection.scopes + [scope] else - source_reflection.scopes + through_reflection.scopes - end - - return @sc - scope_chain = source_reflection.scopes - scope_chain = through_reflection.scopes - - # Add to it the scope from this reflection (if any) - scope_chain.first << scope if scope - - through_scope_chain = through_reflection.scope_chain.map(&:dup) - - if options[:source_type] - through_scope_chain.first << source_type_lambda + source_reflection.scopes end - - # Recursively fill out the rest of the array from the through reflection - scope_chain + through_scope_chain end - def source_type_lambda + def source_type_scope @source_type_lambda ||= begin type = foreign_type source_type = options[:source_type] @@ -853,24 +835,6 @@ def source_type_lambda end end - def scope_chain - @scope_chain ||= begin - scope_chain = source_reflection.scope_chain.map(&:dup) - - # Add to it the scope from this reflection (if any) - scope_chain.first << scope if scope - - through_scope_chain = through_reflection.scope_chain.map(&:dup) - - if options[:source_type] - through_scope_chain.first << source_type_lambda - end - - # Recursively fill out the rest of the array from the through reflection - scope_chain + through_scope_chain - end - end - def has_scope? scope || options[:source_type] || source_reflection.has_scope? || @@ -1043,10 +1007,11 @@ def initialize(reflection, previous_reflection) end def scopes + scopes = @previous_reflection.scopes if @previous_reflection.options[:source_type] - return super + [@previous_reflection.source_type_lambda] + scopes + [@previous_reflection.source_type_scope] else - return super + scopes end end -- GitLab