aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2014-12-26 15:45:34 -0700
committerSean Griffin <sean@thoughtbot.com>2014-12-26 15:46:11 -0700
commitcf03bd45e39def057a2f63e42a3391b7d750dece (patch)
treefcaa683c19db80b8afcf7d6d4893d2361ca40d10
parentbf7c7558b57a36d9997fcbf3aee00e0e493f6649 (diff)
downloadrails-cf03bd45e39def057a2f63e42a3391b7d750dece.tar.gz
rails-cf03bd45e39def057a2f63e42a3391b7d750dece.tar.bz2
rails-cf03bd45e39def057a2f63e42a3391b7d750dece.zip
Allow for handling quoted values in ranges
Since Active Record needs to eagerly cast values, we need to check for quoted infinity in our range handling
-rw-r--r--lib/arel/predications.rb20
-rw-r--r--test/attributes/test_attribute.rb47
2 files changed, 61 insertions, 6 deletions
diff --git a/lib/arel/predications.rb b/lib/arel/predications.rb
index ec779dd40f..b05fc6f99a 100644
--- a/lib/arel/predications.rb
+++ b/lib/arel/predications.rb
@@ -25,15 +25,15 @@ module Arel
end
def between other
- if other.begin == -Float::INFINITY
- if other.end == Float::INFINITY
+ if equals_quoted?(other.begin, -Float::INFINITY)
+ if equals_quoted?(other.end, Float::INFINITY)
not_in([])
elsif other.exclude_end?
lt(other.end)
else
lteq(other.end)
end
- elsif other.end == Float::INFINITY
+ elsif equals_quoted?(other.end, Float::INFINITY)
gteq(other.begin)
elsif other.exclude_end?
gteq(other.begin).and(lt(other.end))
@@ -71,15 +71,15 @@ Passing a range to `#in` is deprecated. Call `#between`, instead.
end
def not_between other
- if other.begin == -Float::INFINITY # The range begins with negative infinity
- if other.end == Float::INFINITY
+ if equals_quoted?(other.begin, -Float::INFINITY)
+ if equals_quoted?(other.end, Float::INFINITY)
self.in([])
elsif other.exclude_end?
gteq(other.end)
else
gt(other.end)
end
- elsif other.end == Float::INFINITY
+ elsif equals_quoted?(other.end, Float::INFINITY)
lt(other.begin)
else
left = lt(other.begin)
@@ -211,5 +211,13 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead.
def quoted_array(others)
others.map { |v| quoted_node(v) }
end
+
+ def equals_quoted?(maybe_quoted, value)
+ if maybe_quoted.is_a?(Nodes::Quoted)
+ maybe_quoted.val == value
+ else
+ maybe_quoted == value
+ end
+ end
end
end
diff --git a/test/attributes/test_attribute.rb b/test/attributes/test_attribute.rb
index 500f9385f8..e4ddb27e72 100644
--- a/test/attributes/test_attribute.rb
+++ b/test/attributes/test_attribute.rb
@@ -1,4 +1,5 @@
require 'helper'
+require 'ostruct'
module Arel
module Attributes
@@ -572,6 +573,16 @@ module Arel
)
end
+ it 'can be constructed with a quoted range starting from -Infinity' do
+ attribute = Attribute.new nil, nil
+ node = attribute.between(quoted_range(-::Float::INFINITY, 3, false))
+
+ node.must_equal Nodes::LessThanOrEqual.new(
+ attribute,
+ Nodes::Quoted.new(3)
+ )
+ end
+
it 'can be constructed with an exclusive range starting from -Infinity' do
attribute = Attribute.new nil, nil
node = attribute.between(-::Float::INFINITY...3)
@@ -582,6 +593,16 @@ module Arel
)
end
+ it 'can be constructed with a quoted exclusive range starting from -Infinity' do
+ attribute = Attribute.new nil, nil
+ node = attribute.between(quoted_range(-::Float::INFINITY, 3, true))
+
+ node.must_equal Nodes::LessThan.new(
+ attribute,
+ Nodes::Quoted.new(3)
+ )
+ end
+
it 'can be constructed with an infinite range' do
attribute = Attribute.new nil, nil
node = attribute.between(-::Float::INFINITY..::Float::INFINITY)
@@ -589,6 +610,14 @@ module Arel
node.must_equal Nodes::NotIn.new(attribute, [])
end
+ it 'can be constructed with a quoted infinite range' do
+ attribute = Attribute.new nil, nil
+ node = attribute.between(quoted_range(-::Float::INFINITY, ::Float::INFINITY, false))
+
+ node.must_equal Nodes::NotIn.new(attribute, [])
+ end
+
+
it 'can be constructed with a range ending at Infinity' do
attribute = Attribute.new nil, nil
node = attribute.between(0..::Float::INFINITY)
@@ -599,6 +628,16 @@ module Arel
)
end
+ it 'can be constructed with a quoted range ending at Infinity' do
+ attribute = Attribute.new nil, nil
+ node = attribute.between(quoted_range(0, ::Float::INFINITY, false))
+
+ node.must_equal Nodes::GreaterThanOrEqual.new(
+ attribute,
+ Nodes::Quoted.new(0)
+ )
+ end
+
it 'can be constructed with an exclusive range' do
attribute = Attribute.new nil, nil
node = attribute.between(0...3)
@@ -614,6 +653,14 @@ module Arel
)
])
end
+
+ def quoted_range(begin_val, end_val, exclude)
+ OpenStruct.new(
+ begin: Nodes::Quoted.new(begin_val),
+ end: Nodes::Quoted.new(end_val),
+ exclude_end?: exclude,
+ )
+ end
end
describe '#in' do