Skip to content

Commit

Permalink
Refactor build_arel: move joins out and simplify havings. [#4860 stat…
Browse files Browse the repository at this point in the history
…e:resolved]

Signed-off-by: José Valim <jose.valim@gmail.com>
  • Loading branch information
miloops authored and josevalim committed Jun 19, 2010
1 parent 02ea1aa commit e061212
Showing 1 changed file with 46 additions and 46 deletions.
92 changes: 46 additions & 46 deletions activerecord/lib/active_record/relation/query_methods.rb
Expand Up @@ -116,45 +116,7 @@ def custom_join_sql(*joins)
def build_arel
arel = table

joined_associations = []
association_joins = []

joins = @joins_values.map {|j| j.respond_to?(:strip) ? j.strip : j}.uniq

joins.each do |join|
association_joins << join if [Hash, Array, Symbol].include?(join.class) && !array_of_strings?(join)
end

stashed_association_joins = joins.select {|j| j.is_a?(ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation)}

non_association_joins = (joins - association_joins - stashed_association_joins).reject {|j| j.blank?}
custom_joins = custom_join_sql(*non_association_joins)

join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, association_joins, custom_joins)

join_dependency.graft(*stashed_association_joins)

@implicit_readonly = true unless association_joins.empty? && stashed_association_joins.empty?

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
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)
arel = build_joins(arel, @joins_values) if @joins_values.present?

@where_values.uniq.each do |where|
next if where.blank?
Expand All @@ -168,9 +130,7 @@ def build_arel
end
end

@having_values.uniq.each do |h|
arel = h.is_a?(String) ? arel.having(h) : arel.having(*h)
end
arel = arel.having(*@having_values.uniq.select{|h| h.present?})

arel = arel.take(@limit_value) if @limit_value.present?
arel = arel.skip(@offset_value) if @offset_value.present?
Expand All @@ -181,18 +141,16 @@ def build_arel

selects = @select_values.uniq

quoted_table_name = @klass.quoted_table_name

if selects.present?
selects.each do |s|
@implicit_readonly = false
arel = arel.project(s) if s.present?
end
else
arel = arel.project(quoted_table_name + '.*')
arel = arel.project(@klass.quoted_table_name + '.*')
end

arel = @from_value.present? ? arel.from(@from_value) : arel.from(quoted_table_name)
arel = @from_value.present? ? arel.from(@from_value) : arel.from(@klass.quoted_table_name)

case @lock_value
when TrueClass
Expand Down Expand Up @@ -221,6 +179,48 @@ def build_where(*args)

private

def build_joins(relation, joins)
joined_associations = []
association_joins = []

joins = @joins_values.map {|j| j.respond_to?(:strip) ? j.strip : j}.uniq

joins.each do |join|
association_joins << join if [Hash, Array, Symbol].include?(join.class) && !array_of_strings?(join)
end

stashed_association_joins = joins.select {|j| j.is_a?(ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation)}

non_association_joins = (joins - association_joins - stashed_association_joins).reject {|j| j.blank?}
custom_joins = custom_join_sql(*non_association_joins)

join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, association_joins, custom_joins)

join_dependency.graft(*stashed_association_joins)

@implicit_readonly = true unless association_joins.empty? && stashed_association_joins.empty?

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
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
relation = relation.join(tj[0], tj[1]).on(*tj[2])
end
end

relation.join(custom_joins)
end

def apply_modules(modules)
values = Array.wrap(modules)
@extensions += values if values.present?
Expand Down

0 comments on commit e061212

Please sign in to comment.