diff options
author | Sean Griffin <sean@thoughtbot.com> | 2014-12-26 15:45:34 -0700 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2014-12-26 15:46:11 -0700 |
commit | cf03bd45e39def057a2f63e42a3391b7d750dece (patch) | |
tree | fcaa683c19db80b8afcf7d6d4893d2361ca40d10 | |
parent | bf7c7558b57a36d9997fcbf3aee00e0e493f6649 (diff) | |
download | rails-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.rb | 20 | ||||
-rw-r--r-- | test/attributes/test_attribute.rb | 47 |
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 |