aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2010-11-17 17:10:40 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2010-11-17 17:10:50 -0800
commit00693209ecc222842949d7cab076f89890cbd507 (patch)
treed18dcccc69ee4c8ffd5143ca8ec4ed85acd2a1ff /activerecord
parent56c5820458fd3981161393c285cce67fdf35e60b (diff)
downloadrails-00693209ecc222842949d7cab076f89890cbd507.tar.gz
rails-00693209ecc222842949d7cab076f89890cbd507.tar.bz2
rails-00693209ecc222842949d7cab076f89890cbd507.zip
collapsing same table / column WHERE clauses to be OR [#4598 state:resolved]
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb29
1 files changed, 25 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 514576564c..07ca2e2088 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -174,10 +174,7 @@ module ActiveRecord
arel = build_joins(arel, @joins_values) unless @joins_values.empty?
- (@where_values - ['']).uniq.each do |where|
- where = Arel.sql(where) if String === where
- arel = arel.where(Arel::Nodes::Grouping.new(where))
- end
+ arel = collapse_wheres(arel, (@where_values - ['']).uniq)
arel = arel.having(*@having_values.uniq.reject{|h| h.blank?}) unless @having_values.empty?
@@ -198,6 +195,30 @@ module ActiveRecord
private
+ def collapse_wheres(arel, wheres)
+ equalities = wheres.grep(Arel::Nodes::Equality)
+
+ groups = equalities.group_by do |equality|
+ left = equality.left
+ # table, column
+ [left.relation.name, left.name]
+ end
+
+ groups.each do |_, eqls|
+ head = eqls.first
+ test = eqls.inject(head) do |memo, expr|
+ expr == head ? expr : memo.or(expr)
+ end
+ arel = arel.where(test)
+ end
+
+ (wheres - equalities).each do |where|
+ where = Arel.sql(where) if String === where
+ arel = arel.where(Arel::Nodes::Grouping.new(where))
+ end
+ arel
+ end
+
def build_where(opts, other = [])
case opts
when String, Array