diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2019-01-03 09:46:42 +0900 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2019-01-08 16:45:17 +0900 |
commit | 7f856c3c8db71e2600d6a84bbc6510eb4ddd0418 (patch) | |
tree | 0a88d5d29152838ecc9495e784f5b6e68aa2b725 | |
parent | a75dea08225285eec5fc199684cd1a51853d2845 (diff) | |
download | rails-7f856c3c8db71e2600d6a84bbc6510eb4ddd0418.tar.gz rails-7f856c3c8db71e2600d6a84bbc6510eb4ddd0418.tar.bz2 rails-7f856c3c8db71e2600d6a84bbc6510eb4ddd0418.zip |
Consolidate the duplicated code that building range predicate
This slightly change the code in the Arel to allow +/-INFINITY as open
ended since the Active Record expects that behavior. See 5ecbeda.
5 files changed, 21 insertions, 36 deletions
diff --git a/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb index 44bb2c7ab6..2ea27c8490 100644 --- a/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb +++ b/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb @@ -3,11 +3,7 @@ module ActiveRecord class PredicateBuilder class RangeHandler # :nodoc: - class RangeWithBinds < Struct.new(:begin, :end) - def exclude_end? - false - end - end + RangeWithBinds = Struct.new(:begin, :end, :exclude_end?) def initialize(predicate_builder) @predicate_builder = predicate_builder @@ -16,22 +12,7 @@ module ActiveRecord def call(attribute, value) begin_bind = predicate_builder.build_bind_attribute(attribute.name, value.begin) end_bind = predicate_builder.build_bind_attribute(attribute.name, value.end) - - if begin_bind.value.infinity? - if end_bind.value.infinity? - attribute.not_in([]) - elsif value.exclude_end? - attribute.lt(end_bind) - else - attribute.lteq(end_bind) - end - elsif end_bind.value.infinity? - attribute.gteq(begin_bind) - elsif value.exclude_end? - attribute.gteq(begin_bind).and(attribute.lt(end_bind)) - else - attribute.between(RangeWithBinds.new(begin_bind, end_bind)) - end + attribute.between(RangeWithBinds.new(begin_bind, end_bind, value.exclude_end?)) end private diff --git a/activerecord/lib/active_record/relation/query_attribute.rb b/activerecord/lib/active_record/relation/query_attribute.rb index f64bd30d38..b45326bdda 100644 --- a/activerecord/lib/active_record/relation/query_attribute.rb +++ b/activerecord/lib/active_record/relation/query_attribute.rb @@ -30,12 +30,12 @@ module ActiveRecord @_boundable = false end - def infinity? - _infinity?(value_before_type_cast) || boundable? && _infinity?(value_for_database) + def infinite? + infinity?(value_before_type_cast) || boundable? && infinity?(value_for_database) end private - def _infinity?(value) + def infinity?(value) value.respond_to?(:infinite?) && value.infinite? end end diff --git a/activerecord/lib/arel/nodes/bind_param.rb b/activerecord/lib/arel/nodes/bind_param.rb index ba8340558a..f145e44ae3 100644 --- a/activerecord/lib/arel/nodes/bind_param.rb +++ b/activerecord/lib/arel/nodes/bind_param.rb @@ -24,6 +24,10 @@ module Arel # :nodoc: all value.nil? end + def infinite? + value.respond_to?(:infinite?) && value.infinite? + end + def boundable? !value.respond_to?(:boundable?) || value.boundable? end diff --git a/activerecord/lib/arel/nodes/casted.rb b/activerecord/lib/arel/nodes/casted.rb index c1e6e97d6d..6e911b717d 100644 --- a/activerecord/lib/arel/nodes/casted.rb +++ b/activerecord/lib/arel/nodes/casted.rb @@ -27,6 +27,10 @@ module Arel # :nodoc: all class Quoted < Arel::Nodes::Unary # :nodoc: alias :val :value def nil?; val.nil?; end + + def infinite? + value.respond_to?(:infinite?) && value.infinite? + end end def self.build_quoted(other, attribute = nil) diff --git a/activerecord/lib/arel/predications.rb b/activerecord/lib/arel/predications.rb index 77502dd199..28679ae892 100644 --- a/activerecord/lib/arel/predications.rb +++ b/activerecord/lib/arel/predications.rb @@ -35,15 +35,15 @@ module Arel # :nodoc: all end def between(other) - if equals_quoted?(other.begin, -Float::INFINITY) - if equals_quoted?(other.end, Float::INFINITY) + if infinity?(other.begin) + if infinity?(other.end) not_in([]) elsif other.exclude_end? lt(other.end) else lteq(other.end) end - elsif equals_quoted?(other.end, Float::INFINITY) + elsif infinity?(other.end) gteq(other.begin) elsif other.exclude_end? gteq(other.begin).and(lt(other.end)) @@ -81,15 +81,15 @@ Passing a range to `#in` is deprecated. Call `#between`, instead. end def not_between(other) - if equals_quoted?(other.begin, -Float::INFINITY) - if equals_quoted?(other.end, Float::INFINITY) + if infinity?(other.begin) + if infinity?(other.end) self.in([]) elsif other.exclude_end? gteq(other.end) else gt(other.end) end - elsif equals_quoted?(other.end, Float::INFINITY) + elsif infinity?(other.end) lt(other.begin) else left = lt(other.begin) @@ -238,12 +238,8 @@ Passing a range to `#not_in` is deprecated. Call `#not_between`, instead. 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 + def infinity?(value) + value.respond_to?(:infinite?) && value.infinite? end end end |