aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation/query_methods.rb
diff options
context:
space:
mode:
authorErnie Miller <ernie@metautonomo.us>2010-04-28 23:14:05 -0400
committerJeremy Kemper <jeremy@bitsweat.net>2010-04-28 20:28:51 -0700
commite33d304975f5b20b0ba819ab644a2a8f80ff3743 (patch)
treebd5e6fa6491a61d19aa4c79c5ee85b53769e7137 /activerecord/lib/active_record/relation/query_methods.rb
parent4e75cc59e70947b794c96894d39c015f9e1cb96c (diff)
downloadrails-e33d304975f5b20b0ba819ab644a2a8f80ff3743.tar.gz
rails-e33d304975f5b20b0ba819ab644a2a8f80ff3743.tar.bz2
rails-e33d304975f5b20b0ba819ab644a2a8f80ff3743.zip
Fix eager loading of associations causing table name collisions
[#4463 state:committed] Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
Diffstat (limited to 'activerecord/lib/active_record/relation/query_methods.rb')
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb73
1 files changed, 42 insertions, 31 deletions
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 58af930446..7bca12d85e 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -80,6 +80,26 @@ module ActiveRecord
@arel ||= build_arel
end
+ def custom_join_sql(*joins)
+ arel = table
+ joins.each do |join|
+ next if join.blank?
+
+ @implicit_readonly = true
+
+ case join
+ when Hash, Array, Symbol
+ if array_of_strings?(join)
+ join_string = join.join(' ')
+ arel = arel.join(join_string)
+ end
+ else
+ arel = arel.join(join)
+ end
+ end
+ arel.joins(arel)
+ end
+
def build_arel
arel = table
@@ -88,50 +108,41 @@ module ActiveRecord
joins = @joins_values.map {|j| j.respond_to?(:strip) ? j.strip : j}.uniq
- # Build association joins first
joins.each do |join|
association_joins << join if [Hash, Array, Symbol].include?(join.class) && !array_of_strings?(join)
end
- if association_joins.any?
- join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, association_joins.uniq, nil)
- to_join = []
+ stashed_association_joins = joins.select {|j| j.is_a?(ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation)}
- join_dependency.join_associations.each do |association|
- if (association_relation = association.relation).is_a?(Array)
- to_join << [association_relation.first, association.association_join.first]
- to_join << [association_relation.last, association.association_join.last]
- else
- to_join << [association_relation, association.association_join]
- end
- end
+ non_association_joins = (joins - association_joins - stashed_association_joins).reject {|j| j.blank?}
+ custom_joins = custom_join_sql(*non_association_joins)
- to_join.each do |tj|
- unless joined_associations.detect {|ja| ja[0] == tj[0] && ja[1] == tj[1] }
- joined_associations << tj
- arel = arel.join(tj[0]).on(*tj[1])
- end
- end
- end
+ join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, association_joins, custom_joins)
- joins.each do |join|
- next if join.blank?
+ join_dependency.graft(*stashed_association_joins)
- @implicit_readonly = true
+ @implicit_readonly = true unless association_joins.empty? && stashed_association_joins.empty?
- case join
- when Relation::JoinOperation
- arel = arel.join(join.relation, join.join_class).on(*join.on)
- when Hash, Array, Symbol
- if array_of_strings?(join)
- join_string = join.join(' ')
- arel = arel.join(join_string)
- end
+ to_join = []
+
+ join_dependency.join_associations.each do |association|
+ if (association_relation = association.relation).is_a?(Array)
+ to_join << [association_relation.first, association.join_class, association.association_join.first]
+ to_join << [association_relation.last, association.join_class, association.association_join.last]
else
- arel = arel.join(join)
+ to_join << [association_relation, association.join_class, association.association_join]
end
end
+ to_join.each do |tj|
+ unless joined_associations.detect {|ja| ja[0] == tj[0] && ja[1] == tj[1] && ja[2] == tj[2] }
+ joined_associations << tj
+ arel = arel.join(tj[0], tj[1]).on(*tj[2])
+ end
+ end
+
+ arel = arel.join(custom_joins)
+
@where_values.uniq.each do |where|
next if where.blank?