rom-repository 0.3.1 → 1.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +11 -13
- data/CHANGELOG.md +25 -0
- data/Gemfile +13 -3
- data/lib/rom/repository.rb +57 -19
- data/lib/rom/repository/changeset.rb +89 -26
- data/lib/rom/repository/changeset/create.rb +34 -0
- data/lib/rom/repository/changeset/delete.rb +15 -0
- data/lib/rom/repository/changeset/pipe.rb +11 -4
- data/lib/rom/repository/changeset/update.rb +11 -1
- data/lib/rom/repository/command_compiler.rb +51 -30
- data/lib/rom/repository/command_proxy.rb +3 -1
- data/lib/rom/repository/header_builder.rb +3 -3
- data/lib/rom/repository/mapper_builder.rb +2 -2
- data/lib/rom/repository/relation_proxy.rb +26 -35
- data/lib/rom/repository/relation_proxy/combine.rb +59 -27
- data/lib/rom/repository/root.rb +4 -6
- data/lib/rom/repository/session.rb +55 -0
- data/lib/rom/repository/struct_builder.rb +29 -17
- data/lib/rom/repository/version.rb +1 -1
- data/lib/rom/struct.rb +11 -20
- data/rom-repository.gemspec +4 -3
- data/spec/integration/command_macros_spec.rb +5 -2
- data/spec/integration/command_spec.rb +0 -6
- data/spec/integration/multi_adapter_spec.rb +8 -5
- data/spec/integration/repository_spec.rb +58 -2
- data/spec/integration/root_repository_spec.rb +9 -2
- data/spec/integration/typed_structs_spec.rb +31 -0
- data/spec/shared/database.rb +5 -1
- data/spec/shared/relations.rb +3 -1
- data/spec/shared/repo.rb +13 -1
- data/spec/shared/structs.rb +39 -0
- data/spec/spec_helper.rb +7 -5
- data/spec/support/mutant.rb +10 -0
- data/spec/unit/changeset/map_spec.rb +42 -0
- data/spec/unit/changeset_spec.rb +32 -6
- data/spec/unit/relation_proxy_spec.rb +27 -9
- data/spec/unit/repository/changeset_spec.rb +125 -0
- data/spec/unit/repository/inspect_spec.rb +18 -0
- data/spec/unit/repository/session_spec.rb +251 -0
- data/spec/unit/session_spec.rb +54 -0
- data/spec/unit/struct_builder_spec.rb +45 -1
- metadata +41 -17
- data/lib/rom/repository/struct_attributes.rb +0 -46
- data/spec/unit/header_builder_spec.rb +0 -73
- data/spec/unit/plugins/view_spec.rb +0 -29
- data/spec/unit/sql/relation_spec.rb +0 -54
- data/spec/unit/struct_spec.rb +0 -22
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'transproc/registry'
|
2
|
+
require 'transproc/transformer'
|
2
3
|
|
3
4
|
module ROM
|
4
5
|
class Changeset
|
5
|
-
class Pipe
|
6
|
+
class Pipe < Transproc::Transformer
|
6
7
|
extend Transproc::Registry
|
7
8
|
|
9
|
+
import Transproc::HashTransformations
|
10
|
+
|
8
11
|
attr_reader :processor
|
9
12
|
|
10
13
|
def self.add_timestamps(data)
|
@@ -16,15 +19,19 @@ module ROM
|
|
16
19
|
data.merge(updated_at: Time.now)
|
17
20
|
end
|
18
21
|
|
19
|
-
def initialize(processor =
|
22
|
+
def initialize(processor = self.class.transproc)
|
20
23
|
@processor = processor
|
21
24
|
end
|
22
25
|
|
26
|
+
def [](name)
|
27
|
+
self.class[name]
|
28
|
+
end
|
29
|
+
|
23
30
|
def >>(other)
|
24
31
|
if processor
|
25
|
-
|
32
|
+
Pipe.new(processor >> other)
|
26
33
|
else
|
27
|
-
|
34
|
+
Pipe.new(other)
|
28
35
|
end
|
29
36
|
end
|
30
37
|
|
@@ -71,12 +71,22 @@ module ROM
|
|
71
71
|
def diff
|
72
72
|
@diff ||=
|
73
73
|
begin
|
74
|
-
new_tuple =
|
74
|
+
new_tuple = __data__.to_a
|
75
75
|
ori_tuple = original.to_a
|
76
76
|
|
77
77
|
Hash[new_tuple - (new_tuple & ori_tuple)]
|
78
78
|
end
|
79
79
|
end
|
80
|
+
|
81
|
+
# @api private
|
82
|
+
def command
|
83
|
+
command_compiler.(command_type, relation, mapper: false).curry(to_h) if diff?
|
84
|
+
end
|
85
|
+
|
86
|
+
# @api private
|
87
|
+
def default_command_type
|
88
|
+
:update
|
89
|
+
end
|
80
90
|
end
|
81
91
|
end
|
82
92
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require '
|
1
|
+
require 'dry/core/inflector'
|
2
|
+
require 'dry/core/cache'
|
2
3
|
|
3
4
|
require 'rom/commands'
|
4
5
|
require 'rom/repository/command_proxy'
|
@@ -13,7 +14,7 @@ module ROM
|
|
13
14
|
#
|
14
15
|
# @api private
|
15
16
|
class CommandCompiler
|
16
|
-
|
17
|
+
extend Dry::Core::Cache
|
17
18
|
|
18
19
|
# Return a specific command type for a given adapter and relation AST
|
19
20
|
#
|
@@ -35,38 +36,31 @@ module ROM
|
|
35
36
|
#
|
36
37
|
# @api private
|
37
38
|
def self.[](*args)
|
38
|
-
|
39
|
-
container, type, adapter, ast, plugins = args
|
39
|
+
fetch_or_store(args.hash) do
|
40
|
+
container, type, adapter, ast, plugins, options = args
|
40
41
|
|
41
|
-
|
42
|
-
raise ArgumentError, "#{type.inspect} is not a supported command type"
|
43
|
-
end
|
44
|
-
|
45
|
-
graph_opts = new(type, adapter, container, registry, plugins).visit(ast)
|
42
|
+
graph_opts = new(type, adapter, container, registry, plugins, options).visit(ast)
|
46
43
|
|
47
44
|
command = ROM::Commands::Graph.build(registry, graph_opts)
|
48
45
|
|
49
46
|
if command.graph?
|
50
47
|
CommandProxy.new(command)
|
51
|
-
|
48
|
+
elsif command.lazy?
|
52
49
|
command.unwrap
|
50
|
+
else
|
51
|
+
command
|
53
52
|
end
|
54
53
|
end
|
55
54
|
end
|
56
55
|
|
57
|
-
# @api private
|
58
|
-
def self.cache
|
59
|
-
@__cache__ ||= Concurrent::Map.new
|
60
|
-
end
|
61
|
-
|
62
56
|
# @api private
|
63
57
|
def self.registry
|
64
58
|
@__registry__ ||= Hash.new { |h, k| h[k] = {} }
|
65
59
|
end
|
66
60
|
|
67
|
-
# @!attribute [r]
|
68
|
-
# @return [Symbol] The command type
|
69
|
-
attr_reader :
|
61
|
+
# @!attribute [r] id
|
62
|
+
# @return [Symbol] The command type registry identifier
|
63
|
+
attr_reader :id
|
70
64
|
|
71
65
|
# @!attribute [r] adapter
|
72
66
|
# @return [Symbol] The adapter identifier ie :sql or :http
|
@@ -84,12 +78,25 @@ module ROM
|
|
84
78
|
# @return [Array<Symbol>] a list of optional plugins that will be enabled for commands
|
85
79
|
attr_reader :plugins
|
86
80
|
|
81
|
+
# @!attribute [r] options
|
82
|
+
# @return [Hash] Additional command options
|
83
|
+
attr_reader :options
|
84
|
+
|
87
85
|
# @api private
|
88
|
-
def initialize(
|
89
|
-
@
|
86
|
+
def initialize(id, adapter, container, registry, plugins, options)
|
87
|
+
@id = id
|
88
|
+
@adapter = adapter
|
90
89
|
@registry = registry
|
91
90
|
@container = container
|
92
91
|
@plugins = Array(plugins)
|
92
|
+
@options = options
|
93
|
+
end
|
94
|
+
|
95
|
+
# @api private
|
96
|
+
def type
|
97
|
+
@_type ||= Commands.const_get(Dry::Core::Inflector.classify(id))[adapter]
|
98
|
+
rescue NameError
|
99
|
+
nil
|
93
100
|
end
|
94
101
|
|
95
102
|
# @api private
|
@@ -109,15 +116,20 @@ module ROM
|
|
109
116
|
if meta[:combine_type] == :many
|
110
117
|
name
|
111
118
|
else
|
112
|
-
{ Inflector.singularize(name).to_sym => name }
|
119
|
+
{ Dry::Core::Inflector.singularize(name).to_sym => name }
|
113
120
|
end
|
114
121
|
|
115
|
-
|
122
|
+
if type
|
123
|
+
register_command(name, type, meta, parent_relation)
|
116
124
|
|
117
|
-
|
118
|
-
|
125
|
+
if other.size > 0
|
126
|
+
[mapping, [type, other]]
|
127
|
+
else
|
128
|
+
[mapping, type]
|
129
|
+
end
|
119
130
|
else
|
120
|
-
[
|
131
|
+
registry[name][id] = container.commands[name][id].with(options)
|
132
|
+
[mapping, id]
|
121
133
|
end
|
122
134
|
end
|
123
135
|
|
@@ -149,7 +161,7 @@ module ROM
|
|
149
161
|
relation = container.relations[rel_name]
|
150
162
|
|
151
163
|
type.create_class(rel_name, type) do |klass|
|
152
|
-
klass.result(meta.fetch(:combine_type,
|
164
|
+
klass.result(meta.fetch(:combine_type, result))
|
153
165
|
|
154
166
|
if meta[:combine_type]
|
155
167
|
setup_associates(klass, relation, meta, parent_relation)
|
@@ -161,6 +173,15 @@ module ROM
|
|
161
173
|
end
|
162
174
|
end
|
163
175
|
|
176
|
+
# Return default result type
|
177
|
+
#
|
178
|
+
# @return [Symbol]
|
179
|
+
#
|
180
|
+
# @api private
|
181
|
+
def result
|
182
|
+
options.fetch(:result, :one)
|
183
|
+
end
|
184
|
+
|
164
185
|
# Sets up `associates` plugin for a given command class and relation
|
165
186
|
#
|
166
187
|
# @param [Class] klass The command class
|
@@ -168,13 +189,11 @@ module ROM
|
|
168
189
|
#
|
169
190
|
# @api private
|
170
191
|
def setup_associates(klass, relation, meta, parent_relation)
|
171
|
-
klass.use(:associates)
|
172
|
-
|
173
192
|
assoc_name =
|
174
193
|
if relation.associations.key?(parent_relation)
|
175
194
|
parent_relation
|
176
195
|
else
|
177
|
-
singular_name = Inflector.singularize(parent_relation).to_sym
|
196
|
+
singular_name = Dry::Core::Inflector.singularize(parent_relation).to_sym
|
178
197
|
singular_name if relation.associations.key?(singular_name)
|
179
198
|
end
|
180
199
|
|
@@ -207,7 +226,9 @@ module ROM
|
|
207
226
|
|
208
227
|
klass.extend_for_relation(relation) if klass.restrictable
|
209
228
|
|
210
|
-
plugins.each
|
229
|
+
plugins.each do |plugin|
|
230
|
+
klass.use(plugin)
|
231
|
+
end
|
211
232
|
end
|
212
233
|
end
|
213
234
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'dry/core/inflector'
|
2
|
+
|
1
3
|
module ROM
|
2
4
|
class Repository
|
3
5
|
# TODO: look into making command graphs work without the root key in the input
|
@@ -7,7 +9,7 @@ module ROM
|
|
7
9
|
|
8
10
|
def initialize(command)
|
9
11
|
@command = command
|
10
|
-
@root = Inflector.singularize(command.name.relation).to_sym
|
12
|
+
@root = Dry::Core::Inflector.singularize(command.name.relation).to_sym
|
11
13
|
end
|
12
14
|
|
13
15
|
def call(input)
|
@@ -49,11 +49,11 @@ module ROM
|
|
49
49
|
node.map { |attribute| visit(attribute, meta) }
|
50
50
|
end
|
51
51
|
|
52
|
-
def visit_attribute(
|
52
|
+
def visit_attribute(attr, meta = {})
|
53
53
|
if meta[:wrap]
|
54
|
-
[name, from:
|
54
|
+
[attr.name, from: attr.alias]
|
55
55
|
else
|
56
|
-
[name]
|
56
|
+
[attr.name]
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'dry/core/cache'
|
2
2
|
require 'rom/mapper'
|
3
3
|
require 'rom/repository/header_builder'
|
4
4
|
|
@@ -6,7 +6,7 @@ module ROM
|
|
6
6
|
class Repository
|
7
7
|
# @api private
|
8
8
|
class MapperBuilder
|
9
|
-
extend Cache
|
9
|
+
extend Dry::Core::Cache
|
10
10
|
|
11
11
|
attr_reader :header_builder
|
12
12
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'rom/
|
1
|
+
require 'rom/initializer'
|
2
2
|
require 'rom/relation/materializable'
|
3
3
|
|
4
4
|
require 'rom/repository/relation_proxy/combine'
|
@@ -14,30 +14,30 @@ module ROM
|
|
14
14
|
#
|
15
15
|
# @api public
|
16
16
|
class RelationProxy
|
17
|
-
|
17
|
+
extend Initializer
|
18
18
|
include Relation::Materializable
|
19
19
|
|
20
20
|
include RelationProxy::Combine
|
21
21
|
include RelationProxy::Wrap
|
22
22
|
|
23
|
-
|
24
|
-
option :mappers, reader: true, default: proc { MapperBuilder.new }
|
25
|
-
option :meta, reader: true, type: Hash, default: EMPTY_HASH
|
26
|
-
option :registry, type: RelationRegistry, default: proc { RelationRegistry.new }, reader: true
|
23
|
+
RelationRegistryType = Types.Definition(RelationRegistry).constrained(type: RelationRegistry)
|
27
24
|
|
28
25
|
# @!attribute [r] relation
|
29
26
|
# @return [Relation, Relation::Composite, Relation::Graph, Relation::Curried] The decorated relation object
|
30
|
-
|
27
|
+
param :relation
|
31
28
|
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
option :name, type: Types::Strict::Symbol
|
30
|
+
option :mappers, reader: true, default: proc { MapperBuilder.new }
|
31
|
+
option :meta, reader: true, default: proc { EMPTY_HASH }
|
32
|
+
option :registry, type: RelationRegistryType, default: proc { RelationRegistry.new }, reader: true
|
35
33
|
|
36
|
-
#
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
# Relation name
|
35
|
+
#
|
36
|
+
# @return [ROM::Relation::Name]
|
37
|
+
#
|
38
|
+
# @api public
|
39
|
+
def name
|
40
|
+
@name == Dry::Initializer::UNDEFINED ? relation.name : relation.name.with(@name)
|
41
41
|
end
|
42
42
|
|
43
43
|
# Materializes wrapped relation and sends it through a mapper
|
@@ -105,15 +105,6 @@ module ROM
|
|
105
105
|
relation.is_a?(Relation::Composite)
|
106
106
|
end
|
107
107
|
|
108
|
-
# Returns meta info for the wrapped relation
|
109
|
-
#
|
110
|
-
# @return [Hash]
|
111
|
-
#
|
112
|
-
# @api private
|
113
|
-
def meta
|
114
|
-
options[:meta]
|
115
|
-
end
|
116
|
-
|
117
108
|
# @return [Symbol] The wrapped relation's adapter identifier ie :sql or :http
|
118
109
|
#
|
119
110
|
# @api private
|
@@ -129,11 +120,9 @@ module ROM
|
|
129
120
|
def to_ast
|
130
121
|
@to_ast ||=
|
131
122
|
begin
|
132
|
-
attr_ast =
|
133
|
-
[:attribute, name]
|
134
|
-
}
|
123
|
+
attr_ast = schema.map { |attr| [:attribute, attr] }
|
135
124
|
|
136
|
-
meta =
|
125
|
+
meta = self.meta.merge(dataset: base_name.dataset)
|
137
126
|
meta.delete(:wraps)
|
138
127
|
|
139
128
|
header = attr_ast + nodes_ast + wraps_ast
|
@@ -147,19 +136,21 @@ module ROM
|
|
147
136
|
relation.respond_to?(meth) || super
|
148
137
|
end
|
149
138
|
|
139
|
+
# @api public
|
140
|
+
def inspect
|
141
|
+
%(#<#{relation.class} name=#{name} dataset=#{dataset.inspect}>)
|
142
|
+
end
|
143
|
+
|
150
144
|
private
|
151
145
|
|
152
146
|
# @api private
|
153
|
-
def
|
154
|
-
relation.
|
147
|
+
def schema
|
148
|
+
meta[:wrap] ? relation.schema.wrap.qualified : relation.schema.reject(&:wrapped?)
|
155
149
|
end
|
156
150
|
|
157
151
|
# @api private
|
158
|
-
def
|
159
|
-
|
160
|
-
prefix = wrap.base_name.dataset
|
161
|
-
wrap.attributes.map { |name| :"#{prefix}_#{name}" }
|
162
|
-
}
|
152
|
+
def base_name
|
153
|
+
relation.base_name
|
163
154
|
end
|
164
155
|
|
165
156
|
# @api private
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'dry/core/inflector'
|
2
|
+
|
1
3
|
module ROM
|
2
4
|
class Repository
|
3
5
|
class RelationProxy
|
@@ -56,12 +58,30 @@ module ROM
|
|
56
58
|
|
57
59
|
combine_opts = Hash.new { |h, k| h[k] = {} }
|
58
60
|
|
59
|
-
options.each do |
|
60
|
-
if
|
61
|
-
|
61
|
+
options.each do |key, value|
|
62
|
+
if key == :one || key == :many
|
63
|
+
if value.is_a?(Hash)
|
64
|
+
value.each do |name, spec|
|
65
|
+
if spec.is_a?(Array)
|
66
|
+
combine_opts[key][name] = spec
|
67
|
+
else
|
68
|
+
_, (curried, keys) = combine_opts_from_relations(spec).to_a[0]
|
69
|
+
combine_opts[key][name] = [curried, keys]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
else
|
73
|
+
_, (curried, keys) = combine_opts_from_relations(value).to_a[0]
|
74
|
+
combine_opts[key][curried.combine_tuple_key(key)] = [curried, keys]
|
75
|
+
end
|
62
76
|
else
|
63
|
-
|
64
|
-
|
77
|
+
if value.is_a?(Array)
|
78
|
+
curried = combine_from_assoc(key, registry[key]).combine(*value)
|
79
|
+
result, _, keys = combine_opts_for_assoc(key)
|
80
|
+
combine_opts[result][key] = [curried, keys]
|
81
|
+
else
|
82
|
+
result, curried, keys = combine_opts_for_assoc(key, value)
|
83
|
+
combine_opts[result][key] = [curried, keys]
|
84
|
+
end
|
65
85
|
end
|
66
86
|
end
|
67
87
|
|
@@ -97,18 +117,21 @@ module ROM
|
|
97
117
|
when Hash
|
98
118
|
parents.each_with_object({}) { |(name, parent), r|
|
99
119
|
keys = combine_keys(parent, relation, :parent)
|
100
|
-
|
120
|
+
curried = combine_from_assoc_with_fallback(name, parent, keys)
|
121
|
+
r[name] = [curried, keys]
|
101
122
|
}
|
102
123
|
when Array
|
103
124
|
parents.each_with_object({}) { |parent, r|
|
104
|
-
tuple_key = parent.combine_tuple_key(type)
|
105
125
|
keys = combine_keys(parent, relation, :parent)
|
106
|
-
|
126
|
+
tuple_key = parent.combine_tuple_key(type)
|
127
|
+
curried = combine_from_assoc_with_fallback(parent.name, parent, keys)
|
128
|
+
r[tuple_key] = [curried, keys]
|
107
129
|
}
|
108
130
|
else
|
109
|
-
tuple_key = parents.combine_tuple_key(type)
|
110
131
|
keys = combine_keys(parents, relation, :parent)
|
111
|
-
|
132
|
+
tuple_key = parents.combine_tuple_key(type)
|
133
|
+
curried = combine_from_assoc_with_fallback(parents.name, parents, keys)
|
134
|
+
{ tuple_key => [curried, keys] }
|
112
135
|
end
|
113
136
|
end
|
114
137
|
|
@@ -138,18 +161,21 @@ module ROM
|
|
138
161
|
when Hash
|
139
162
|
children.each_with_object({}) { |(name, child), r|
|
140
163
|
keys = combine_keys(relation, child, :children)
|
141
|
-
|
164
|
+
curried = combine_from_assoc_with_fallback(name, child, keys)
|
165
|
+
r[name] = [curried, keys]
|
142
166
|
}
|
143
167
|
when Array
|
144
|
-
|
145
|
-
tuple_key = parent.combine_tuple_key(type)
|
168
|
+
children.each_with_object({}) { |child, r|
|
146
169
|
keys = combine_keys(relation, child, :children)
|
147
|
-
|
170
|
+
tuple_key = child.combine_tuple_key(type)
|
171
|
+
curried = combine_from_assoc_with_fallback(child.name, child, keys)
|
172
|
+
r[tuple_key] = [curried, keys]
|
148
173
|
}
|
149
174
|
else
|
150
|
-
tuple_key = children.combine_tuple_key(type)
|
151
175
|
keys = combine_keys(relation, children, :children)
|
152
|
-
|
176
|
+
curried = combine_from_assoc_with_fallback(children.name, children, keys)
|
177
|
+
tuple_key = children.combine_tuple_key(type)
|
178
|
+
{ tuple_key => [curried, keys] }
|
153
179
|
end
|
154
180
|
end
|
155
181
|
|
@@ -185,15 +211,19 @@ module ROM
|
|
185
211
|
# and this mapping is used by `combine` to build a full relation graph
|
186
212
|
#
|
187
213
|
# @api private
|
188
|
-
def combine_opts_from_relations(relations)
|
189
|
-
relations.each_with_object({}) do |
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
214
|
+
def combine_opts_from_relations(*relations)
|
215
|
+
relations.each_with_object({}) do |spec, h|
|
216
|
+
# We assume it's a child relation
|
217
|
+
keys = combine_keys(relation, spec, :children)
|
218
|
+
rel = combine_from_assoc_with_fallback(spec.name, spec, keys)
|
219
|
+
h[spec.name.relation] = [rel, keys]
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
# @api private
|
224
|
+
def combine_from_assoc_with_fallback(name, other, keys)
|
225
|
+
combine_from_assoc(name, other) do
|
226
|
+
other.combine_method(relation, keys)
|
197
227
|
end
|
198
228
|
end
|
199
229
|
|
@@ -205,6 +235,7 @@ module ROM
|
|
205
235
|
#
|
206
236
|
# @api private
|
207
237
|
def combine_from_assoc(name, other, &fallback)
|
238
|
+
return other if other.curried?
|
208
239
|
associations.try(name) { |assoc| other.for_combine(assoc) } or fallback.call
|
209
240
|
end
|
210
241
|
|
@@ -214,9 +245,10 @@ module ROM
|
|
214
245
|
# This is used when a flat list of association names was passed to `combine`
|
215
246
|
#
|
216
247
|
# @api private
|
217
|
-
def combine_opts_for_assoc(name)
|
248
|
+
def combine_opts_for_assoc(name, opts = nil)
|
218
249
|
assoc = relation.associations[name]
|
219
250
|
curried = registry[assoc.target.relation].for_combine(assoc)
|
251
|
+
curried = curried.combine(opts) unless opts.nil?
|
220
252
|
keys = assoc.combine_keys(__registry__)
|
221
253
|
[assoc.result, curried, keys]
|
222
254
|
end
|
@@ -258,7 +290,7 @@ module ROM
|
|
258
290
|
# @api private
|
259
291
|
def combine_tuple_key(result)
|
260
292
|
if result == :one
|
261
|
-
Inflector.singularize(base_name.relation).to_sym
|
293
|
+
Dry::Core::Inflector.singularize(base_name.relation).to_sym
|
262
294
|
else
|
263
295
|
base_name.relation
|
264
296
|
end
|