aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation/query_methods.rb
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2015-01-28 14:04:26 -0700
committerSean Griffin <sean@thoughtbot.com>2015-01-28 14:35:03 -0700
commitff45b9e9f7c4ff0fb4fdab8beb539913b876d63b (patch)
tree1513baae2abecb8e0ce14fe21ae8563c876d25ab /activerecord/lib/active_record/relation/query_methods.rb
parentb0b37942d729b6bdcd2e3178eda7fa1de203b3d0 (diff)
downloadrails-ff45b9e9f7c4ff0fb4fdab8beb539913b876d63b.tar.gz
rails-ff45b9e9f7c4ff0fb4fdab8beb539913b876d63b.tar.bz2
rails-ff45b9e9f7c4ff0fb4fdab8beb539913b876d63b.zip
Bring the implementation of Relation#or up to speed
Diffstat (limited to 'activerecord/lib/active_record/relation/query_methods.rb')
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb44
1 files changed, 8 insertions, 36 deletions
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 78ee8b4580..b0edb3b1f2 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -596,50 +596,22 @@ module ActiveRecord
spawn.or!(other)
end
- def or!(other)
- combining = group_values.any? ? :having : :where
-
- unless structurally_compatible?(other, combining)
+ def or!(other) # :nodoc:
+ unless structurally_compatible_for_or?(other)
raise ArgumentError, 'Relation passed to #or must be structurally compatible'
end
- unless other.is_a?(NullRelation)
- left_values = send("#{combining}_values")
- right_values = other.send("#{combining}_values")
-
- common = left_values & right_values
- mine = left_values - common
- theirs = right_values - common
-
- if mine.any? && theirs.any?
- mine = mine.map { |x| String === x ? Arel.sql(x) : x }
- theirs = theirs.map { |x| String === x ? Arel.sql(x) : x }
-
- mine = [Arel::Nodes::And.new(mine)] if mine.size > 1
- theirs = [Arel::Nodes::And.new(theirs)] if theirs.size > 1
-
- common << Arel::Nodes::Or.new(mine.first, theirs.first)
- end
-
- send("#{combining}_values=", common)
- end
+ self.where_clause = self.where_clause.or(other.where_clause)
+ self.having_clause = self.having_clause.or(other.having_clause)
self
end
- def structurally_compatible?(other, allowed_to_vary)
- Relation::SINGLE_VALUE_METHODS.all? do |name|
- send("#{name}_value") == other.send("#{name}_value")
- end &&
- (Relation::MULTI_VALUE_METHODS - [allowed_to_vary, :extending]).all? do |name|
- send("#{name}_values") == other.send("#{name}_values")
- end &&
- (extending_values - [NullRelation]) == (other.extending_values - [NullRelation]) &&
- !limit_value &&
- !offset_value &&
- !uniq_value
+ private def structurally_compatible_for_or?(other) # :nodoc:
+ Relation::SINGLE_VALUE_METHODS.all? { |m| send("#{m}_value") == other.send("#{m}_value") } &&
+ (Relation::MULTI_VALUE_METHODS - [:extending]).all? { |m| send("#{m}_values") == other.send("#{m}_values") } &&
+ (Relation::CLAUSE_METHODS - [:having, :where]).all? { |m| send("#{m}_clause") != other.send("#{m}_clause") }
end
- private :structurally_compatible?
# Allows to specify a HAVING clause. Note that you can't use HAVING
# without also specifying a GROUP clause.