From 3086881001ed0007eee76f23cf54a7dda88bf792 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 13 Jan 2014 10:58:48 -0800 Subject: bubble bind parameters up when building join dependencies --- .../lib/active_record/associations/join_dependency.rb | 8 ++++---- .../associations/join_dependency/join_association.rb | 13 ++++++++++--- activerecord/lib/active_record/relation/query_methods.rb | 7 +++++-- 3 files changed, 19 insertions(+), 9 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb index 295dccf34e..b5f9ee6cee 100644 --- a/activerecord/lib/active_record/associations/join_dependency.rb +++ b/activerecord/lib/active_record/associations/join_dependency.rb @@ -164,17 +164,17 @@ module ActiveRecord def make_outer_joins(parent, child) tables = table_aliases_for(parent, child) join_type = Arel::OuterJoin - joins = make_constraints parent, child, tables, join_type + info = make_constraints parent, child, tables, join_type - joins.concat child.children.flat_map { |c| make_outer_joins(child, c) } + [info] + child.children.flat_map { |c| make_outer_joins(child, c) } end def make_inner_joins(parent, child) tables = child.tables join_type = Arel::InnerJoin - joins = make_constraints parent, child, tables, join_type + info = make_constraints parent, child, tables, join_type - joins.concat child.children.flat_map { |c| make_inner_joins(child, c) } + [info] + child.children.flat_map { |c| make_inner_joins(child, c) } end def table_aliases_for(parent, node) 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 84e18684d8..303ee3682f 100644 --- a/activerecord/lib/active_record/associations/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/join_dependency/join_association.rb @@ -21,8 +21,11 @@ module ActiveRecord super && reflection == other.reflection end + JoinInformation = Struct.new :joins, :binds + def join_constraints(foreign_table, foreign_klass, node, join_type, tables, scope_chain, chain) joins = [] + bind_values = [] tables = tables.reverse scope_chain_iter = scope_chain.reverse_each @@ -64,8 +67,12 @@ module ActiveRecord left.merge right end - if rel && !rel.arel.constraints.empty? - constraint = constraint.and rel.arel.constraints + if rel + bind_values.concat rel.bind_values + + if !rel.arel.constraints.empty? + constraint = constraint.and rel.arel.constraints + end end joins << table.create_join(table, table.create_on(constraint), join_type) @@ -74,7 +81,7 @@ module ActiveRecord foreign_table, foreign_klass = table, klass end - joins + JoinInformation.new joins, bind_values end # Builds equality condition. diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index fc653f467c..6cc5585b27 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -1006,9 +1006,12 @@ module ActiveRecord join_list ) - joins = join_dependency.join_constraints stashed_association_joins + join_infos = join_dependency.join_constraints stashed_association_joins - joins.each { |join| manager.from(join) } + join_infos.each do |info| + info.joins.each { |join| manager.from(join) } + self.bind_values += info.binds + end manager.join_sources.concat(join_list) -- cgit v1.2.3