Simplify ActiveModel & ActiveRecord Type::Registry
ActiveRecord::Type::Registry doesn't need to inherit from ActiveModel::Type::Registry, and it makes both classes more simple. Co-authored-by: Adrianna Chang <adrianna.chang@shopify.com>
This commit is contained in:
parent
7fd8079ef2
commit
81d0653f84
|
@ -24,9 +24,10 @@ module ActiveModel
|
|||
class << self
|
||||
attr_accessor :registry # :nodoc:
|
||||
|
||||
# Add a new type to the registry, allowing it to be gotten through ActiveModel::Type#lookup
|
||||
def register(type_name, klass = nil, **options, &block)
|
||||
registry.register(type_name, klass, **options, &block)
|
||||
# Add a new type to the registry, allowing it to be referenced as a
|
||||
# symbol by {attribute}[rdoc-ref:Attributes::ClassMethods#attribute].
|
||||
def register(type_name, klass = nil, &block)
|
||||
registry.register(type_name, klass, &block)
|
||||
end
|
||||
|
||||
def lookup(*args, **kwargs) # :nodoc:
|
||||
|
|
|
@ -1,31 +1,30 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActiveModel
|
||||
# :stopdoc:
|
||||
module Type
|
||||
class Registry
|
||||
class Registry # :nodoc:
|
||||
def initialize
|
||||
@registrations = []
|
||||
@registrations = {}
|
||||
end
|
||||
|
||||
def initialize_dup(other)
|
||||
def initialize_copy(other)
|
||||
@registrations = @registrations.dup
|
||||
super
|
||||
end
|
||||
|
||||
def register(type_name, klass = nil, **options, &block)
|
||||
def register(type_name, klass = nil, &block)
|
||||
unless block_given?
|
||||
block = proc { |_, *args| klass.new(*args) }
|
||||
block.ruby2_keywords if block.respond_to?(:ruby2_keywords)
|
||||
end
|
||||
registrations << registration_klass.new(type_name, block, **options)
|
||||
registrations[type_name] = block
|
||||
end
|
||||
|
||||
def lookup(symbol, *args, **kwargs)
|
||||
registration = find_registration(symbol, *args, **kwargs)
|
||||
registration = registrations[symbol]
|
||||
|
||||
if registration
|
||||
registration.call(self, symbol, *args, **kwargs)
|
||||
registration.call(symbol, *args, **kwargs)
|
||||
else
|
||||
raise ArgumentError, "Unknown type #{symbol.inspect}"
|
||||
end
|
||||
|
@ -33,38 +32,6 @@ module ActiveModel
|
|||
|
||||
private
|
||||
attr_reader :registrations
|
||||
|
||||
def registration_klass
|
||||
Registration
|
||||
end
|
||||
|
||||
def find_registration(symbol, *args, **kwargs)
|
||||
registrations.find { |r| r.matches?(symbol, *args, **kwargs) }
|
||||
end
|
||||
end
|
||||
|
||||
class Registration
|
||||
# Options must be taken because of https://bugs.ruby-lang.org/issues/10856
|
||||
def initialize(name, block, **)
|
||||
@name = name
|
||||
@block = block
|
||||
end
|
||||
|
||||
def call(_registry, *args, **kwargs)
|
||||
if kwargs.any? # https://bugs.ruby-lang.org/issues/10856
|
||||
block.call(*args, **kwargs)
|
||||
else
|
||||
block.call(*args)
|
||||
end
|
||||
end
|
||||
|
||||
def matches?(type_name, *args, **kwargs)
|
||||
type_name == name
|
||||
end
|
||||
|
||||
private
|
||||
attr_reader :name, :block
|
||||
end
|
||||
end
|
||||
# :startdoc:
|
||||
end
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "cases/helper"
|
||||
|
||||
module ActiveModel
|
||||
class TypeTest < ActiveModel::TestCase
|
||||
setup do
|
||||
@old_registry = ActiveModel::Type.registry
|
||||
ActiveModel::Type.registry = @old_registry.dup
|
||||
end
|
||||
|
||||
teardown do
|
||||
ActiveModel::Type.registry = @old_registry
|
||||
end
|
||||
|
||||
test "registering a new type" do
|
||||
type = Struct.new(:args)
|
||||
ActiveModel::Type.register(:foo, type)
|
||||
|
||||
assert_equal type.new(:arg), ActiveModel::Type.lookup(:foo, :arg)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,15 +5,40 @@ require "active_model/type/registry"
|
|||
module ActiveRecord
|
||||
# :stopdoc:
|
||||
module Type
|
||||
class AdapterSpecificRegistry < ActiveModel::Type::Registry
|
||||
class AdapterSpecificRegistry # :nodoc:
|
||||
def initialize
|
||||
@registrations = []
|
||||
end
|
||||
|
||||
def initialize_copy(other)
|
||||
@registrations = @registrations.dup
|
||||
super
|
||||
end
|
||||
|
||||
def add_modifier(options, klass, **args)
|
||||
registrations << DecorationRegistration.new(options, klass, **args)
|
||||
end
|
||||
|
||||
private
|
||||
def registration_klass
|
||||
Registration
|
||||
def register(type_name, klass = nil, **options, &block)
|
||||
unless block_given?
|
||||
block = proc { |_, *args| klass.new(*args) }
|
||||
block.ruby2_keywords if block.respond_to?(:ruby2_keywords)
|
||||
end
|
||||
registrations << Registration.new(type_name, block, **options)
|
||||
end
|
||||
|
||||
def lookup(symbol, *args, **kwargs)
|
||||
registration = find_registration(symbol, *args, **kwargs)
|
||||
|
||||
if registration
|
||||
registration.call(self, symbol, *args, **kwargs)
|
||||
else
|
||||
raise ArgumentError, "Unknown type #{symbol.inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
attr_reader :registrations
|
||||
|
||||
def find_registration(symbol, *args, **kwargs)
|
||||
registrations
|
||||
|
@ -22,7 +47,7 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
class Registration
|
||||
class Registration # :nodoc:
|
||||
def initialize(name, block, adapter: nil, override: nil)
|
||||
@name = name
|
||||
@block = block
|
||||
|
@ -89,7 +114,7 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
class DecorationRegistration < Registration
|
||||
class DecorationRegistration < Registration # :nodoc:
|
||||
def initialize(options, klass, adapter: nil)
|
||||
@options = options
|
||||
@klass = klass
|
||||
|
@ -120,7 +145,7 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
class TypeConflictError < StandardError
|
||||
class TypeConflictError < StandardError # :nodoc:
|
||||
end
|
||||
# :startdoc:
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue