aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation/where_clause.rb
diff options
context:
space:
mode:
authorMaxime Lapointe <hunter_spawn@hotmail.com>2017-07-25 14:00:39 -0400
committerMaxime Lapointe <hunter_spawn@hotmail.com>2017-07-25 22:17:47 -0400
commit110e0e1fcceab68716e0c75d87baffb14403b288 (patch)
treea41c218554b33a6aca16e66965d6c8d061e0c6d3 /activerecord/lib/active_record/relation/where_clause.rb
parent6f9b01c056cd2f3a4761baf78df207e1154f1b06 (diff)
downloadrails-110e0e1fcceab68716e0c75d87baffb14403b288.tar.gz
rails-110e0e1fcceab68716e0c75d87baffb14403b288.tar.bz2
rails-110e0e1fcceab68716e0c75d87baffb14403b288.zip
Avoid duplicate clauses when using #or
Condenses the clauses that are common to both sides of the OR and put them outside, before the OR This fix the current behavior where the number of conditions is exponential based on the number of times #or is used.
Diffstat (limited to 'activerecord/lib/active_record/relation/where_clause.rb')
-rw-r--r--activerecord/lib/active_record/relation/where_clause.rb25
1 files changed, 16 insertions, 9 deletions
diff --git a/activerecord/lib/active_record/relation/where_clause.rb b/activerecord/lib/active_record/relation/where_clause.rb
index ef2bca9155..5b68c25bdd 100644
--- a/activerecord/lib/active_record/relation/where_clause.rb
+++ b/activerecord/lib/active_record/relation/where_clause.rb
@@ -15,6 +15,12 @@ module ActiveRecord
)
end
+ def -(other)
+ WhereClause.new(
+ predicates - other.predicates,
+ )
+ end
+
def merge(other)
WhereClause.new(
predicates_unreferenced_by(other) + other.predicates,
@@ -26,15 +32,16 @@ module ActiveRecord
end
def or(other)
- if empty?
- self
- elsif other.empty?
- other
- else
- WhereClause.new(
- [ast.or(other.ast)],
- )
- end
+ left = self - other
+ common = self - left
+ right = other - common
+
+ return common if left.empty? || right.empty?
+
+ or_clause = WhereClause.new(
+ [left.ast.or(right.ast)]
+ )
+ common + or_clause
end
def to_h(table_name = nil)