mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #41866 from etiennebarrie/simplify-active-model-record-registry
Simplify ActiveModel & ActiveRecord Type::Registry
This commit is contained in:
commit
57cbf4136f
4 changed files with 66 additions and 50 deletions
|
@ -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
|
||||
|
|
23
activemodel/test/cases/type_test.rb
Normal file
23
activemodel/test/cases/type_test.rb
Normal file
|
@ -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 a new issue