Skip to content

Commit

Permalink
Allow to configure custom inflector
Browse files Browse the repository at this point in the history
WIP but registration already works
  • Loading branch information
flash-gordon committed Mar 9, 2020
1 parent 98bc111 commit 34b5a9f
Show file tree
Hide file tree
Showing 20 changed files with 149 additions and 29 deletions.
2 changes: 1 addition & 1 deletion core/lib/rom/associations/through_identifier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def self.[](source, target, assoc_name = nil)

# @api private
def self.default_assoc_name(relation)
Inflector.singularize(relation).to_sym
relation.inflector.singularize(relation).to_sym
end

# @api private
Expand Down
11 changes: 8 additions & 3 deletions core/lib/rom/command_compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ def self.registry
# @return [Cache] local cache instance
option :cache, default: -> { Cache.new }

# @!attribute [r] inflector
# @return [Dry::Inflector] String inflector
# @api private
option :inflector, default: -> { Inflector }

# Return a specific command type for a given adapter and relation AST
#
# This class holds its own registry where all generated commands are being
Expand Down Expand Up @@ -114,7 +119,7 @@ def call(*args)

# @api private
def type
@_type ||= Commands.const_get(Inflector.classify(id))[adapter]
@_type ||= Commands.const_get(inflector.classify(id))[adapter]
rescue NameError
nil
end
Expand All @@ -139,7 +144,7 @@ def visit_relation(node, parent_relation = nil)
if meta[:combine_type] == :many
name
else
{ Inflector.singularize(name).to_sym => name }
{ inflector.singularize(name).to_sym => name }
end

mapping =
Expand Down Expand Up @@ -237,7 +242,7 @@ def setup_associates(klass, relation, _meta, parent_relation)
if relation.associations.key?(parent_relation)
parent_relation
else
singular_name = Inflector.singularize(parent_relation).to_sym
singular_name = inflector.singularize(parent_relation).to_sym
singular_name if relation.associations.key?(singular_name)
end

Expand Down
2 changes: 1 addition & 1 deletion core/lib/rom/command_proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class CommandProxy
attr_reader :command, :root

# @api private
def initialize(command, root = Inflector.singularize(command.name.relation).to_sym)
def initialize(command, inflector: nil, root: inflector.singularize(command.name.relation).to_sym)
@command = command
@root = root
end
Expand Down
3 changes: 2 additions & 1 deletion core/lib/rom/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require 'rom/setup'
require 'rom/configuration_dsl'
require 'rom/support/notifications'
require 'rom/support/inflector'

module ROM
class Configuration
Expand Down Expand Up @@ -38,7 +39,7 @@ class Configuration

def_delegators :@setup, :register_relation, :register_command, :register_mapper, :register_plugin,
:command_classes, :mapper_classes,
:auto_registration
:auto_registration, :inflector, :inflector=

def_delegators :@environment, :gateways, :gateways_map, :configure, :config

Expand Down
11 changes: 6 additions & 5 deletions core/lib/rom/configuration_dsl/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ class Command
# @api private
def self.build_class(name, relation, options = EMPTY_HASH, &block)
type = options.fetch(:type) { name }
command_type = Inflector.classify(type)
inflector = options.fetch(:inflector) { Inflector }
command_type = inflector.classify(type)
adapter = options.fetch(:adapter)
parent = ROM::Command.adapter_namespace(adapter).const_get(command_type)
class_name = generate_class_name(adapter, command_type, relation)
class_name = generate_class_name(adapter, command_type, relation, inflector)

Dry::Core::ClassBuilder.new(name: class_name, parent: parent).call do |klass|
klass.register_as(name)
Expand All @@ -31,11 +32,11 @@ def self.build_class(name, relation, options = EMPTY_HASH, &block)
# Create a command subclass name based on adapter, type and relation
#
# @api private
def self.generate_class_name(adapter, command_type, relation)
def self.generate_class_name(adapter, command_type, relation, inflector)
pieces = ['ROM']
pieces << Inflector.classify(adapter)
pieces << inflector.classify(adapter)
pieces << 'Commands'
pieces << "#{command_type}[#{Inflector.classify(relation)}s]"
pieces << "#{command_type}[#{inflector.classify(relation)}s]"
pieces.join('::')
end
end
Expand Down
3 changes: 2 additions & 1 deletion core/lib/rom/configuration_dsl/relation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class Relation
#
# @api private
def self.build_class(name, options = EMPTY_HASH)
class_name = "ROM::Relation[#{Inflector.camelize(name)}]"
inflector = options.fetch(:inflector) { Inflector }
class_name = "ROM::Relation[#{inflector.camelize(name)}]"
adapter = options.fetch(:adapter)

Dry::Core::ClassBuilder.new(name: class_name, parent: ROM::Relation[adapter]).call do |klass|
Expand Down
8 changes: 7 additions & 1 deletion core/lib/rom/relation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require 'rom/constants'
require 'rom/initializer'
require 'rom/support/memoizable'
require 'rom/support/inflector'

require 'rom/relation/class_interface'

Expand Down Expand Up @@ -189,6 +190,11 @@ class Relation
# @api private
option :meta, reader: true, default: -> { EMPTY_HASH }

# @!attribute [r] inflector
# @return [Dry::Inflector] String inflector
# @api private
option :inflector, reader: true, default: -> { Inflector }

# Return schema attribute
#
# @example accessing canonical attribute
Expand Down Expand Up @@ -596,7 +602,7 @@ def foreign_key(name)
if attr
attr.name
else
:"#{Inflector.singularize(name.dataset)}_id"
:"#{inflector.singularize(name.dataset)}_id"
end
end

Expand Down
11 changes: 8 additions & 3 deletions core/lib/rom/schema/associations_dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,23 @@ class Schema
# This DSL is exposed in `associations do .. end` blocks in schema defintions.
#
# @api public
class AssociationsDSL < BasicObject
class AssociationsDSL < ::BasicObject
# @!attribute [r] source
# @return [Relation::Name] The source relation
attr_reader :source

# @!attribute [r] inflector
# @return [Dry::Inflector] String inflector
attr_reader :inflector

# @!attribute [r] registry
# @return [RelationRegistry] Relations registry from a rom container
attr_reader :registry

# @api private
def initialize(source, &block)
def initialize(source, inflector = ::ROM::Inflector, &block)
@source = source
@inflector = inflector
@registry = {}
instance_exec(&block)
end
Expand Down Expand Up @@ -199,7 +204,7 @@ def add(association)

# @api private
def dataset_name(name)
Inflector.pluralize(name).to_sym
inflector.pluralize(name).to_sym
end
end
end
Expand Down
12 changes: 8 additions & 4 deletions core/lib/rom/setup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@ class Setup
# @api private
attr_reader :notifications

# @api private
attr_accessor :inflector

# @api private
def initialize(notifications)
@relation_classes = []
@command_classes = []
@mapper_classes = []
@plugins = []
@notifications = notifications
@inflector = Inflector
end

# Enable auto-registration for a given setup object
Expand All @@ -47,7 +51,7 @@ def initialize(notifications)
#
# @api public
def auto_registration(directory, **options)
auto_registration = AutoRegistration.new(directory, **options)
auto_registration = AutoRegistration.new(directory, inflector: inflector, **options)
auto_registration.relations.map { |r| register_relation(r) }
auto_registration.commands.map { |r| register_command(r) }
auto_registration.mappers.map { |r| register_mapper(r) }
Expand All @@ -58,21 +62,21 @@ def auto_registration(directory, **options)
#
# @api private
def register_relation(*klasses)
klasses.reduce(@relation_classes, :<<)
@relation_classes.concat(klasses)
end

# Mapper sub-classes are being registered with this method during setup
#
# @api private
def register_mapper(*klasses)
klasses.reduce(@mapper_classes, :<<)
@mapper_classes.concat(klasses)
end

# Command sub-classes are being registered with this method during setup
#
# @api private
def register_command(*klasses)
klasses.reduce(@command_classes, :<<)
@command_classes.concat(klasses)
end

# @api private
Expand Down
21 changes: 17 additions & 4 deletions core/lib/rom/setup/auto_registration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class AutoRegistration

PathnameType = Types.Constructor(Pathname, &Kernel.method(:Pathname))

InflectorType = Types.Strict(Dry::Inflector)

DEFAULT_MAPPING = {
relations: :relations,
mappers: :mappers,
Expand Down Expand Up @@ -51,6 +53,11 @@ class AutoRegistration
]
}

# @!attribute [r] inflector
# @return [Dry::Inflector] String inflector
# @api private
option :inflector, type: InflectorType, default: -> { Inflector }

# Load relation files
#
# @api private
Expand Down Expand Up @@ -84,19 +91,25 @@ def load_entities(entity)
case namespace
when String
AutoRegistrationStrategies::CustomNamespace.new(
namespace: namespace, file: file, directory: directory
namespace: namespace,
file: file,
directory: directory,
inflector: inflector
).call
when TrueClass
AutoRegistrationStrategies::WithNamespace.new(
file: file, directory: directory
file: file, directory: directory, inflector: inflector
).call
when FalseClass
AutoRegistrationStrategies::NoNamespace.new(
file: file, directory: directory, entity: component_dirs.fetch(entity)
file: file,
directory: directory,
entity: component_dirs.fetch(entity),
inflector: inflector
).call
end

Inflector.constantize(klass_name)
inflector.constantize(klass_name)
end
end
end
Expand Down
6 changes: 6 additions & 0 deletions core/lib/rom/setup/auto_registration_strategies/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require 'rom/types'
require 'rom/initializer'
require 'rom/support/inflector'

module ROM
module AutoRegistrationStrategies
Expand All @@ -18,6 +19,11 @@ class Base
# @!attribute [r] file
# @return [String] Name of a component file
option :file, type: Types::Strict::String

# @!attribute [r] inflector
# @return [Dry::Inflector] String inflector
# @api private
option :inflector, reader: true, default: -> { Inflector }
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class CustomNamespace < Base
#
# @api private
def call
parts = path_arr.map { |part| Inflector.camelize(part) }
parts = path_arr.map { |part| inflector.camelize(part) }
potential = parts.map.with_index do |_, i|
parts[(i - parts.size)..parts.size]
end
Expand Down Expand Up @@ -66,7 +66,7 @@ def filename

# @api private
def ns_const
@namespace_constant ||= Inflector.constantize(namespace)
@namespace_constant ||= inflector.constantize(namespace)
end

# @api private
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class NoNamespace < Base
#
# @api private
def call
Inflector.camelize(
inflector.camelize(
file.sub(%r{^#{directory}/#{entity}/}, '').sub(EXTENSION_REGEX, '')
)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class WithNamespace < Base
#
# @api private
def call
Inflector.camelize(
inflector.camelize(
file.sub(%r{^#{directory.dirname}/}, '').sub(EXTENSION_REGEX, '')
)
end
Expand Down
5 changes: 4 additions & 1 deletion core/lib/rom/struct_compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ class StructCompiler < Dry::Types::Compiler
extend Initializer

param :registry, default: -> { Dry::Types }

option :cache, default: -> { Cache.new }

option :inflector, reader: true, default: -> { Inflector }

# @api private
def initialize(*)
super
Expand Down Expand Up @@ -105,7 +108,7 @@ def build_class(name, parent, ns, &block)

# @api private
def class_name(name)
Inflector.classify(name)
inflector.classify(name)
end
end
end
8 changes: 8 additions & 0 deletions core/spec/fixtures/xml_space/xml_commands/create_customer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

module XMLSpace
module XMLCommands
class CreateCustomer
end
end
end
8 changes: 8 additions & 0 deletions core/spec/fixtures/xml_space/xml_mappers/customer_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

module XMLSpace
module XMLMappers
class CustomerList
end
end
end
8 changes: 8 additions & 0 deletions core/spec/fixtures/xml_space/xml_relations/customers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

module XMLSpace
module XMLRelations
class Customers
end
end
end
Loading

0 comments on commit 34b5a9f

Please sign in to comment.