diff options
author | Sean Griffin <sean@thoughtbot.com> | 2014-12-26 14:17:22 -0700 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2014-12-26 14:18:26 -0700 |
commit | 392a453b10abad60432f2612000f306de55b7d1a (patch) | |
tree | 32d3216bacb4c51e1f1d112b3f4cdac590e3973c /activerecord/lib/active_record/relation | |
parent | a3936bbe21f4bff8247f890cacfd0fc882921003 (diff) | |
download | rails-392a453b10abad60432f2612000f306de55b7d1a.tar.gz rails-392a453b10abad60432f2612000f306de55b7d1a.tar.bz2 rails-392a453b10abad60432f2612000f306de55b7d1a.zip |
Re-use the predicate builder in the `ArrayHandler`
This reduces the number of places which will need to care about single
value or range specific logic as we introduce type casting. The array
handler is only responsible for producing `in` statements.
/cc @mrgilman
[Sean Griffin & Melanie Gilman]
Diffstat (limited to 'activerecord/lib/active_record/relation')
-rw-r--r-- | activerecord/lib/active_record/relation/predicate_builder.rb | 10 | ||||
-rw-r--r-- | activerecord/lib/active_record/relation/predicate_builder/array_handler.rb | 14 |
2 files changed, 16 insertions, 8 deletions
diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index 71bb795d5b..61db27d150 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -17,7 +17,7 @@ module ActiveRecord register_handler(Base, BaseHandler.new) register_handler(Range, RangeHandler.new) register_handler(Relation, RelationHandler.new) - register_handler(Array, ArrayHandler.new) + register_handler(Array, ArrayHandler.new(self)) end def resolve_column_aliases(hash) @@ -93,6 +93,10 @@ module ActiveRecord @handlers.unshift([klass, handler]) end + def build(attribute, value) + handler_for(value).call(attribute, value) + end + protected attr_reader :klass, :table @@ -129,10 +133,6 @@ module ActiveRecord attributes end - def build(attribute, value) - handler_for(value).call(attribute, value) - end - def handler_for(object) @handlers.detect { |klass, _| klass === object }.last end diff --git a/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb index 58bccf2167..4b5f5773a0 100644 --- a/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb +++ b/activerecord/lib/active_record/relation/predicate_builder/array_handler.rb @@ -3,6 +3,10 @@ require 'active_support/core_ext/string/filters' module ActiveRecord class PredicateBuilder class ArrayHandler # :nodoc: + def initialize(predicate_builder) + @predicate_builder = predicate_builder + end + def call(attribute, value) values = value.map { |x| x.is_a?(Base) ? x.id : x } nils, values = values.partition(&:nil?) @@ -14,19 +18,23 @@ module ActiveRecord values_predicate = case values.length when 0 then NullPredicate - when 1 then attribute.eq(values.first) + when 1 then predicate_builder.build(attribute, values.first) else attribute.in(values) end unless nils.empty? - values_predicate = values_predicate.or(attribute.eq(nil)) + values_predicate = values_predicate.or(predicate_builder.build(attribute, nil)) end - array_predicates = ranges.map { |range| attribute.between(range) } + array_predicates = ranges.map { |range| predicate_builder.build(attribute, range) } array_predicates.unshift(values_predicate) array_predicates.inject { |composite, predicate| composite.or(predicate) } end + protected + + attr_reader :predicate_builder + module NullPredicate # :nodoc: def self.or(other) other |