Skip to content

Commit a51556b

Browse files
flash-gordonsolnic
authored andcommitted
Allow to configure custom inflector
1 parent 4b6d826 commit a51556b

30 files changed

+308
-78
lines changed

lib/rom/associations/definitions/abstract.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
require "rom/initializer"
88
require "rom/relation/name"
99
require "rom/associations/through_identifier"
10+
require "rom/support/inflector"
1011

1112
module ROM
1213
module Associations
@@ -94,7 +95,12 @@ def self.process_options(target, options)
9495
through = options[:through]
9596

9697
if through
97-
options[:through] = ThroughIdentifier[through, target.relation, options[:assoc]]
98+
options[:through] = ThroughIdentifier[
99+
through,
100+
target.relation,
101+
options[:assoc],
102+
inflector: options.fetch(:inflector, Inflector)
103+
]
98104
end
99105

100106
options[:name] = target.relation

lib/rom/associations/through_identifier.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ class ThroughIdentifier
1616
attr_reader :assoc_name
1717

1818
# @api private
19-
def self.[](source, target, assoc_name = nil)
20-
new(source, target, assoc_name || default_assoc_name(target))
19+
def self.[](source, target, assoc_name = nil, inflector: Inflector)
20+
new(source, target, assoc_name || default_assoc_name(target, inflector: inflector))
2121
end
2222

2323
# @api private
24-
def self.default_assoc_name(relation)
25-
Inflector.singularize(relation).to_sym
24+
def self.default_assoc_name(relation, inflector:)
25+
inflector.singularize(relation).to_sym
2626
end
2727

2828
# @api private

lib/rom/command_compiler.rb

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ def self.registry
6666
# @return [Cache] local cache instance
6767
option :cache, default: -> { Cache.new }
6868

69+
# @!attribute [r] inflector
70+
# @return [Dry::Inflector] String inflector
71+
# @api private
72+
option :inflector, default: -> { Inflector }
73+
6974
# Return a specific command type for a given adapter and relation AST
7075
#
7176
# This class holds its own registry where all generated commands are being
@@ -102,7 +107,8 @@ def call(*args)
102107
command = ROM::Commands::Graph.build(registry, graph_opts)
103108

104109
if command.graph?
105-
CommandProxy.new(command)
110+
root = inflector.singularize(command.name.relation).to_sym
111+
CommandProxy.new(command, root)
106112
elsif command.lazy?
107113
command.unwrap
108114
else
@@ -114,7 +120,7 @@ def call(*args)
114120

115121
# @api private
116122
def type
117-
@_type ||= Commands.const_get(Inflector.classify(id))[adapter]
123+
@_type ||= Commands.const_get(inflector.classify(id))[adapter]
118124
rescue NameError
119125
nil
120126
end
@@ -139,7 +145,7 @@ def visit_relation(node, parent_relation = nil)
139145
if meta[:combine_type] == :many
140146
name
141147
else
142-
{Inflector.singularize(name).to_sym => name}
148+
{inflector.singularize(name).to_sym => name}
143149
end
144150

145151
mapping =
@@ -190,7 +196,7 @@ def visit_attribute(*_args)
190196
def register_command(rel_name, type, rel_meta, parent_relation = nil)
191197
relation = relations[rel_name]
192198

193-
type.create_class(rel_name, type) do |klass|
199+
type.create_class(rel_name, type, inflector: inflector) do |klass|
194200
klass.result(rel_meta.fetch(:combine_type, result))
195201

196202
meta.each do |name, value|
@@ -237,7 +243,7 @@ def setup_associates(klass, relation, _meta, parent_relation)
237243
if relation.associations.key?(parent_relation)
238244
parent_relation
239245
else
240-
singular_name = Inflector.singularize(parent_relation).to_sym
246+
singular_name = inflector.singularize(parent_relation).to_sym
241247
singular_name if relation.associations.key?(singular_name)
242248
end
243249

lib/rom/command_proxy.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ module ROM
88
#
99
# @api private
1010
class CommandProxy
11-
attr_reader :command, :root
11+
attr_reader :command
12+
13+
attr_reader :root
1214

1315
# @api private
14-
def initialize(command, root = Inflector.singularize(command.name.relation).to_sym)
16+
def initialize(command, root)
1517
@command = command
1618
@root = root
1719
end
@@ -23,7 +25,7 @@ def call(input)
2325

2426
# @api private
2527
def >>(other)
26-
self.class.new(command >> other)
28+
self.class.new(command >> other, root)
2729
end
2830

2931
# @api private

lib/rom/commands/class_interface.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ def build(relation, **options)
8585
# @return [Class, Object]
8686
#
8787
# @api public
88-
def create_class(name, type, &block)
88+
def create_class(name, type, inflector: Inflector, &block)
8989
klass = Dry::Core::ClassBuilder
90-
.new(name: "#{Inflector.classify(type)}[:#{name}]", parent: type)
90+
.new(name: "#{inflector.classify(type)}[:#{name}]", parent: type)
9191
.call
9292

9393
if block

lib/rom/configuration.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
require "rom/setup"
77
require "rom/configuration_dsl"
88
require "rom/support/notifications"
9+
require "rom/support/inflector"
910

1011
module ROM
1112
class Configuration
@@ -38,7 +39,7 @@ class Configuration
3839

3940
def_delegators :@setup, :register_relation, :register_command, :register_mapper, :register_plugin,
4041
:command_classes, :mapper_classes,
41-
:auto_registration
42+
:auto_registration, :inflector, :inflector=
4243

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

lib/rom/configuration_dsl/command.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ class Command
1616
# @api private
1717
def self.build_class(name, relation, options = EMPTY_HASH, &block)
1818
type = options.fetch(:type) { name }
19-
command_type = Inflector.classify(type)
19+
inflector = options.fetch(:inflector) { Inflector }
20+
command_type = inflector.classify(type)
2021
adapter = options.fetch(:adapter)
2122
parent = ROM::Command.adapter_namespace(adapter).const_get(command_type)
22-
class_name = generate_class_name(adapter, command_type, relation)
23+
class_name = generate_class_name(adapter, command_type, relation, inflector)
2324

2425
Dry::Core::ClassBuilder.new(name: class_name, parent: parent).call do |klass|
2526
klass.register_as(name)
@@ -31,11 +32,11 @@ def self.build_class(name, relation, options = EMPTY_HASH, &block)
3132
# Create a command subclass name based on adapter, type and relation
3233
#
3334
# @api private
34-
def self.generate_class_name(adapter, command_type, relation)
35+
def self.generate_class_name(adapter, command_type, relation, inflector)
3536
pieces = ["ROM"]
36-
pieces << Inflector.classify(adapter)
37+
pieces << inflector.classify(adapter)
3738
pieces << "Commands"
38-
pieces << "#{command_type}[#{Inflector.classify(relation)}s]"
39+
pieces << "#{command_type}[#{inflector.classify(relation)}s]"
3940
pieces.join("::")
4041
end
4142
end

lib/rom/configuration_dsl/relation.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ class Relation
1515
#
1616
# @api private
1717
def self.build_class(name, options = EMPTY_HASH)
18-
class_name = "ROM::Relation[#{Inflector.camelize(name)}]"
18+
inflector = options.fetch(:inflector) { Inflector }
19+
class_name = "ROM::Relation[#{inflector.camelize(name)}]"
1920
adapter = options.fetch(:adapter)
2021

2122
Dry::Core::ClassBuilder.new(name: class_name, parent: ROM::Relation[adapter]).call do |klass|

lib/rom/create_container.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ def finalize(environment, setup)
3434
mappers: setup.mapper_classes,
3535
plugins: setup.plugins,
3636
notifications: setup.notifications,
37-
config: environment.config.dup.freeze
37+
config: environment.config.dup.freeze,
38+
inflector: setup.inflector
3839
)
3940

4041
finalize.run!

lib/rom/relation.rb

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
require "rom/constants"
77
require "rom/initializer"
88
require "rom/support/memoizable"
9+
require "rom/support/inflector"
910

1011
require "rom/relation/class_interface"
1112

@@ -136,17 +137,26 @@ class Relation
136137
# @api public
137138
param :dataset
138139

140+
# @!attribute [r] inflector
141+
# @return [Dry::Inflector] String inflector
142+
# @api private
143+
option :inflector, reader: true, default: -> { Inflector }
144+
139145
# @!attribute [r] schema
140146
# @return [Schema] relation schema, defaults to class-level canonical
141147
# schema (if it was defined) and sets an empty one as
142148
# the fallback
143149
# @api public
144-
option :schema, default: -> { self.class.schema || self.class.default_schema }
150+
option :schema, default: -> {
151+
self.class.schema || self.class.default_schema(inflector: inflector)
152+
}
145153

146154
# @!attribute [r] name
147155
# @return [Object] The relation name
148156
# @api public
149-
option :name, default: -> { self.class.schema ? self.class.schema.name : self.class.default_name }
157+
option :name, default: -> {
158+
self.class.schema ? self.class.schema.name : self.class.default_name(inflector)
159+
}
150160

151161
# @!attribute [r] input_schema
152162
# @return [Object#[]] tuple processing function, uses schema or defaults to Hash[]
@@ -596,7 +606,7 @@ def foreign_key(name)
596606
if attr
597607
attr.name
598608
else
599-
:"#{Inflector.singularize(name.dataset)}_id"
609+
:"#{inflector.singularize(name.dataset)}_id"
600610
end
601611
end
602612

0 commit comments

Comments
 (0)