aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2014-12-26 14:12:16 -0700
committerSean Griffin <sean@thoughtbot.com>2014-12-26 14:12:16 -0700
commita3936bbe21f4bff8247f890cacfd0fc882921003 (patch)
tree615ff2d3ed709121f8aea1a2cd6eb56870af0ce9 /activerecord
parentaf55197d86676c371a0a50e62c162df4d6006849 (diff)
downloadrails-a3936bbe21f4bff8247f890cacfd0fc882921003.tar.gz
rails-a3936bbe21f4bff8247f890cacfd0fc882921003.tar.bz2
rails-a3936bbe21f4bff8247f890cacfd0fc882921003.zip
Change `PredicateBuilder` handler methods to instance methods
This will allow us to pass the predicate builder into the constructor of these handlers. The procs had to be changed to objects, because the `PredicateBuilder` needs to be marshalable. If we ever decide to make `register_handler` part of the public API, we should come up with a better solution which allows procs. /cc @mrgilman [Sean Griffin & Melanie Gilman]
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder.rb55
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/base_handler.rb9
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/basic_object_handler.rb9
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/class_handler.rb19
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/range_handler.rb9
-rw-r--r--activerecord/test/cases/relation/predicate_builder_test.rb4
6 files changed, 74 insertions, 31 deletions
diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index 67e646bf18..71bb795d5b 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -1,13 +1,23 @@
module ActiveRecord
class PredicateBuilder # :nodoc:
- @handlers = []
-
- autoload :RelationHandler, 'active_record/relation/predicate_builder/relation_handler'
- autoload :ArrayHandler, 'active_record/relation/predicate_builder/array_handler'
+ require 'active_record/relation/predicate_builder/array_handler'
+ require 'active_record/relation/predicate_builder/base_handler'
+ require 'active_record/relation/predicate_builder/basic_object_handler'
+ require 'active_record/relation/predicate_builder/class_handler'
+ require 'active_record/relation/predicate_builder/range_handler'
+ require 'active_record/relation/predicate_builder/relation_handler'
def initialize(klass, table)
@klass = klass
@table = table
+ @handlers = []
+
+ register_handler(BasicObject, BasicObjectHandler.new)
+ register_handler(Class, ClassHandler.new)
+ register_handler(Base, BaseHandler.new)
+ register_handler(Range, RangeHandler.new)
+ register_handler(Relation, RelationHandler.new)
+ register_handler(Array, ArrayHandler.new)
end
def resolve_column_aliases(hash)
@@ -35,13 +45,13 @@ module ActiveRecord
# PriceEstimate.where(estimate_of: treasure)
if klass && reflection = klass._reflect_on_association(column)
if reflection.polymorphic? && base_class = polymorphic_base_class_from_value(value)
- queries << self.class.build(table[reflection.foreign_type], base_class.name)
+ queries << build(table[reflection.foreign_type], base_class.name)
end
column = reflection.foreign_key
end
- queries << self.class.build(table[column], value)
+ queries << build(table[column], value)
queries
end
@@ -79,33 +89,10 @@ module ActiveRecord
# )
# end
# ActiveRecord::PredicateBuilder.register_handler(MyCustomDateRange, handler)
- def self.register_handler(klass, handler)
+ def register_handler(klass, handler)
@handlers.unshift([klass, handler])
end
- register_handler(BasicObject, ->(attribute, value) { attribute.eq(value) })
- register_handler(Class, ->(attribute, value) { deprecate_class_handler; attribute.eq(value.name) })
- register_handler(Base, ->(attribute, value) { attribute.eq(value.id) })
- register_handler(Range, ->(attribute, value) { attribute.between(value) })
- register_handler(Relation, RelationHandler.new)
- register_handler(Array, ArrayHandler.new)
-
- def self.build(attribute, value)
- handler_for(value).call(attribute, value)
- end
-
- def self.handler_for(object)
- @handlers.detect { |klass, _| klass === object }.last
- end
- private_class_method :handler_for
-
- def self.deprecate_class_handler
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
- Passing a class as a value in an Active Record query is deprecated and
- will be removed. Pass a string instead.
- MSG
- end
-
protected
attr_reader :klass, :table
@@ -141,5 +128,13 @@ 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
end
end
diff --git a/activerecord/lib/active_record/relation/predicate_builder/base_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/base_handler.rb
new file mode 100644
index 0000000000..d50ea519f9
--- /dev/null
+++ b/activerecord/lib/active_record/relation/predicate_builder/base_handler.rb
@@ -0,0 +1,9 @@
+module ActiveRecord
+ class PredicateBuilder
+ class BaseHandler # :nodoc:
+ def call(attribute, value)
+ attribute.eq(value.id)
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler.rb
new file mode 100644
index 0000000000..79cde00303
--- /dev/null
+++ b/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler.rb
@@ -0,0 +1,9 @@
+module ActiveRecord
+ class PredicateBuilder
+ class BasicObjectHandler # :nodoc:
+ def call(attribute, value)
+ attribute.eq(value)
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/relation/predicate_builder/class_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/class_handler.rb
new file mode 100644
index 0000000000..3fe1642ed0
--- /dev/null
+++ b/activerecord/lib/active_record/relation/predicate_builder/class_handler.rb
@@ -0,0 +1,19 @@
+module ActiveRecord
+ class PredicateBuilder
+ class ClassHandler # :nodoc:
+ def call(attribute, value)
+ print_deprecation_warning
+ attribute.eq(value.name)
+ end
+
+ private
+
+ def print_deprecation_warning
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
+ Passing a class as a value in an Active Record query is deprecated and
+ will be removed. Pass a string instead.
+ MSG
+ end
+ end
+ end
+end
diff --git a/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb
new file mode 100644
index 0000000000..47dc46bb4b
--- /dev/null
+++ b/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb
@@ -0,0 +1,9 @@
+module ActiveRecord
+ class PredicateBuilder
+ class RangeHandler # :nodoc:
+ def call(attribute, value)
+ attribute.between(value)
+ end
+ end
+ end
+end
diff --git a/activerecord/test/cases/relation/predicate_builder_test.rb b/activerecord/test/cases/relation/predicate_builder_test.rb
index 4057835688..0cc081fced 100644
--- a/activerecord/test/cases/relation/predicate_builder_test.rb
+++ b/activerecord/test/cases/relation/predicate_builder_test.rb
@@ -4,11 +4,13 @@ require 'models/topic'
module ActiveRecord
class PredicateBuilderTest < ActiveRecord::TestCase
def test_registering_new_handlers
- PredicateBuilder.register_handler(Regexp, proc do |column, value|
+ Topic.predicate_builder.register_handler(Regexp, proc do |column, value|
Arel::Nodes::InfixOperation.new('~', column, Arel.sql(value.source))
end)
assert_match %r{["`]topics["`].["`]title["`] ~ rails}i, Topic.where(title: /rails/).to_sql
+ ensure
+ Topic.reset_column_information
end
end
end