rom-repository 1.4.0 → 2.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/CHANGELOG.md +14 -6
- data/{LICENSE.txt → LICENSE} +1 -1
- data/README.md +18 -1
- data/lib/rom-repository.rb +1 -2
- data/lib/rom/repository.rb +9 -216
- data/lib/rom/repository/class_interface.rb +16 -33
- data/lib/rom/repository/relation_reader.rb +46 -0
- data/lib/rom/repository/root.rb +3 -59
- data/lib/rom/repository/version.rb +1 -1
- metadata +9 -98
- data/.gitignore +0 -3
- data/.rspec +0 -3
- data/.travis.yml +0 -27
- data/.yardopts +0 -2
- data/Gemfile +0 -38
- data/Rakefile +0 -19
- data/lib/rom/open_struct.rb +0 -35
- data/lib/rom/repository/changeset.rb +0 -155
- data/lib/rom/repository/changeset/associated.rb +0 -100
- data/lib/rom/repository/changeset/create.rb +0 -16
- data/lib/rom/repository/changeset/delete.rb +0 -17
- data/lib/rom/repository/changeset/pipe.rb +0 -97
- data/lib/rom/repository/changeset/restricted.rb +0 -28
- data/lib/rom/repository/changeset/stateful.rb +0 -282
- data/lib/rom/repository/changeset/update.rb +0 -82
- data/lib/rom/repository/command_compiler.rb +0 -257
- data/lib/rom/repository/command_proxy.rb +0 -26
- data/lib/rom/repository/header_builder.rb +0 -65
- data/lib/rom/repository/mapper_builder.rb +0 -23
- data/lib/rom/repository/relation_proxy.rb +0 -337
- data/lib/rom/repository/relation_proxy/combine.rb +0 -320
- data/lib/rom/repository/relation_proxy/wrap.rb +0 -78
- data/lib/rom/repository/struct_builder.rb +0 -83
- data/lib/rom/struct.rb +0 -113
- data/log/.gitkeep +0 -0
- data/rom-repository.gemspec +0 -23
- data/spec/integration/changeset_spec.rb +0 -193
- data/spec/integration/command_macros_spec.rb +0 -191
- data/spec/integration/command_spec.rb +0 -228
- data/spec/integration/multi_adapter_spec.rb +0 -73
- data/spec/integration/repository/aggregate_spec.rb +0 -58
- data/spec/integration/repository_spec.rb +0 -406
- data/spec/integration/root_repository_spec.rb +0 -106
- data/spec/integration/typed_structs_spec.rb +0 -64
- data/spec/shared/database.rb +0 -79
- data/spec/shared/mappers.rb +0 -35
- data/spec/shared/models.rb +0 -41
- data/spec/shared/plugins.rb +0 -66
- data/spec/shared/relations.rb +0 -115
- data/spec/shared/repo.rb +0 -86
- data/spec/shared/seeds.rb +0 -30
- data/spec/shared/structs.rb +0 -140
- data/spec/spec_helper.rb +0 -83
- data/spec/support/mapper_registry.rb +0 -9
- data/spec/support/mutant.rb +0 -10
- data/spec/unit/changeset/associate_spec.rb +0 -120
- data/spec/unit/changeset/map_spec.rb +0 -111
- data/spec/unit/changeset_spec.rb +0 -186
- data/spec/unit/relation_proxy_spec.rb +0 -202
- data/spec/unit/repository/changeset_spec.rb +0 -197
- data/spec/unit/repository/inspect_spec.rb +0 -18
- data/spec/unit/repository/session_spec.rb +0 -251
- data/spec/unit/repository/transaction_spec.rb +0 -42
- data/spec/unit/session_spec.rb +0 -46
- data/spec/unit/struct_builder_spec.rb +0 -128
@@ -1,58 +0,0 @@
|
|
1
|
-
RSpec.describe ROM::Repository::Root, '#aggregate' do
|
2
|
-
subject(:repo) do
|
3
|
-
Class.new(ROM::Repository[:users]) do
|
4
|
-
relations :tasks, :posts, :labels
|
5
|
-
end.new(rom)
|
6
|
-
end
|
7
|
-
|
8
|
-
include_context 'database'
|
9
|
-
include_context 'relations'
|
10
|
-
include_context 'seeds'
|
11
|
-
|
12
|
-
it 'loads a graph with aliased children and its parents' do
|
13
|
-
user = repo.aggregate(aliased_posts: :author).first
|
14
|
-
|
15
|
-
expect(user.aliased_posts.count).to be(1)
|
16
|
-
expect(user.aliased_posts[0].author.id).to be(user.id)
|
17
|
-
expect(user.aliased_posts[0].author.name).to eql(user.name)
|
18
|
-
end
|
19
|
-
|
20
|
-
|
21
|
-
it 'exposes nodes via `node` method' do
|
22
|
-
jane = repo.
|
23
|
-
aggregate(:posts).
|
24
|
-
node(:posts) { |posts| posts.where(title: 'Another one') }.
|
25
|
-
where(name: 'Jane').one
|
26
|
-
|
27
|
-
expect(jane.name).to eql('Jane')
|
28
|
-
expect(jane.posts).to be_empty
|
29
|
-
|
30
|
-
repo.posts.insert author_id: 1, title: 'Another one'
|
31
|
-
|
32
|
-
jane = repo.
|
33
|
-
aggregate(:posts).
|
34
|
-
node(:posts) { |posts| posts.where(title: 'Another one') }.
|
35
|
-
where(name: 'Jane').one
|
36
|
-
|
37
|
-
expect(jane.name).to eql('Jane')
|
38
|
-
expect(jane.posts.size).to be(1)
|
39
|
-
expect(jane.posts[0].title).to eql('Another one')
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'exposes nested nodes via `node` method' do
|
43
|
-
jane = repo.
|
44
|
-
aggregate(posts: :labels).
|
45
|
-
node(posts: :labels) { |labels| labels.where(name: 'red') }.
|
46
|
-
where(name: 'Jane').one
|
47
|
-
|
48
|
-
expect(jane.name).to eql('Jane')
|
49
|
-
expect(jane.posts.size).to be(1)
|
50
|
-
expect(jane.posts[0].labels.size).to be(1)
|
51
|
-
expect(jane.posts[0].labels[0].name).to eql('red')
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'raises arg error when invalid relation name was passed to `node` method' do
|
55
|
-
expect { repo.aggregate(:posts).node(:poztz) {} }.
|
56
|
-
to raise_error(ArgumentError, ':poztz is not a valid aggregate node name')
|
57
|
-
end
|
58
|
-
end
|
@@ -1,406 +0,0 @@
|
|
1
|
-
RSpec.describe 'ROM repository' do
|
2
|
-
include_context 'database'
|
3
|
-
include_context 'relations'
|
4
|
-
include_context 'repo'
|
5
|
-
include_context 'structs'
|
6
|
-
include_context 'seeds'
|
7
|
-
|
8
|
-
it 'loads a single relation' do
|
9
|
-
expect(repo.all_users.to_a).to match_array([jane, joe])
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'can be used with a custom mapper' do
|
13
|
-
expect(repo.all_users_as_users.to_a).to match_array([
|
14
|
-
Test::Models::User.new(jane),
|
15
|
-
Test::Models::User.new(joe)
|
16
|
-
])
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'loads a relation by an association' do
|
20
|
-
expect(repo.tasks_for_users(repo.all_users)).to match_array([jane_task, joe_task])
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'loads a combine relation with one parent' do
|
24
|
-
task = repo.task_with_user.first
|
25
|
-
|
26
|
-
expect(task.id).to eql(task_with_user.id)
|
27
|
-
expect(task.title).to eql(task_with_user.title)
|
28
|
-
expect(task.user.id).to eql(task_with_user.user.id)
|
29
|
-
expect(task.user.name).to eql(task_with_user.user.name)
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'loads a combine relation with one parent with custom tuple key' do
|
33
|
-
expect(repo.task_with_owner.first).to eql(task_with_owner)
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'loads a combined relation with many children' do
|
37
|
-
expect(repo.users_with_tasks.to_a).to match_array([jane_with_tasks, joe_with_tasks])
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'loads a combined relation with one child' do
|
41
|
-
expect(repo.users_with_task.to_a).to match_array([jane_with_task, joe_with_task])
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'loads a combined relation with one child restricted by given criteria' do
|
45
|
-
expect(repo.users_with_task_by_title('Joe Task').to_a).to match_array([
|
46
|
-
jane_without_task, joe_with_task
|
47
|
-
])
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'loads nested combined relations' do
|
51
|
-
user = repo.users_with_tasks_and_tags.first
|
52
|
-
|
53
|
-
expect(user.id).to be(1)
|
54
|
-
expect(user.name).to eql('Jane')
|
55
|
-
expect(user.all_tasks.size).to be(1)
|
56
|
-
expect(user.all_tasks[0].id).to be(2)
|
57
|
-
expect(user.all_tasks[0].title).to eql('Jane Task')
|
58
|
-
expect(user.all_tasks[0].tags.size).to be(1)
|
59
|
-
expect(user.all_tasks[0].tags[0].name).to eql('red')
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'loads nested combined relations using configured associations' do
|
63
|
-
jane = repo.users_with_posts_and_their_labels.first
|
64
|
-
|
65
|
-
expect(jane.posts.size).to be(1)
|
66
|
-
expect(jane.posts.map(&:title)).to eql(['Hello From Jane'])
|
67
|
-
expect(jane.posts.flat_map(&:labels).flat_map(&:name)).to eql(%w(red blue))
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'loads a wrapped relation' do
|
71
|
-
expect(repo.tag_with_wrapped_task.first).to eql(tag_with_task)
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'loads wraps using aliased relation' do
|
75
|
-
author = repo.users.where(name: 'Jane').one
|
76
|
-
|
77
|
-
repo.command(:create, repo.books).(title: 'Hello World', author_id: author.id)
|
78
|
-
|
79
|
-
book = repo.books.wrap(:author).to_a.first
|
80
|
-
|
81
|
-
expect(book.author.id).to eql(author.id)
|
82
|
-
expect(book.author.name).to eql(author.name)
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'loads multiple wraps' do
|
86
|
-
post_label = repo.posts_labels.wrap(:post).wrap(:label).to_a.first
|
87
|
-
|
88
|
-
expect(post_label.label_id).to be(post_label.label.id)
|
89
|
-
expect(post_label.post_id).to be(post_label.post.id)
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'loads an aggregate via custom fks' do
|
93
|
-
jane = repo.aggregate(many: repo.posts).where(name: 'Jane').one
|
94
|
-
|
95
|
-
expect(jane.posts.size).to be(1)
|
96
|
-
expect(jane.posts.first.title).to eql('Hello From Jane')
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'loads an aggregate via assoc name' do
|
100
|
-
jane = repo.aggregate(:posts).where(name: 'Jane').one
|
101
|
-
|
102
|
-
expect(jane.posts.size).to be(1)
|
103
|
-
expect(jane.posts.first.title).to eql('Hello From Jane')
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'loads an aggregate via assoc options' do
|
107
|
-
jane = repo.aggregate(posts: :labels).where(name: 'Jane').one
|
108
|
-
|
109
|
-
expect(jane.name).to eql('Jane')
|
110
|
-
expect(jane.posts.size).to be(1)
|
111
|
-
expect(jane.posts.first.title).to eql('Hello From Jane')
|
112
|
-
expect(jane.posts[0].labels.size).to be(2)
|
113
|
-
expect(jane.posts[0].labels[0].name).to eql('red')
|
114
|
-
expect(jane.posts[0].labels[1].name).to eql('blue')
|
115
|
-
end
|
116
|
-
|
117
|
-
it 'loads an aggregate with multiple assoc options' do
|
118
|
-
jane = repo.aggregate(:labels, posts: :labels).where(name: 'Jane').one
|
119
|
-
|
120
|
-
expect(jane.name).to eql('Jane')
|
121
|
-
|
122
|
-
expect(jane.labels.size).to be(2)
|
123
|
-
expect(jane.labels[0].name).to eql('red')
|
124
|
-
expect(jane.labels[1].name).to eql('blue')
|
125
|
-
|
126
|
-
expect(jane.posts.size).to be(1)
|
127
|
-
expect(jane.posts[0].title).to eql('Hello From Jane')
|
128
|
-
|
129
|
-
expect(jane.posts[0].labels.size).to be(2)
|
130
|
-
expect(jane.posts[0].labels[0].name).to eql('red')
|
131
|
-
expect(jane.posts[0].labels[1].name).to eql('blue')
|
132
|
-
end
|
133
|
-
|
134
|
-
it 'loads an aggregate with deeply nested assoc options' do
|
135
|
-
jane = repo.aggregate(posts: [{ author: :labels }]).where(name: 'Jane').one
|
136
|
-
|
137
|
-
expect(jane.posts.size).to be(1)
|
138
|
-
expect(jane.posts[0].title).to eql('Hello From Jane')
|
139
|
-
|
140
|
-
expect(jane.posts[0].author.id).to eql(jane.id)
|
141
|
-
expect(jane.posts[0].author.labels.size).to be(2)
|
142
|
-
expect(jane.posts[0].author.labels[0].name).to eql('red')
|
143
|
-
expect(jane.posts[0].author.labels[1].name).to eql('blue')
|
144
|
-
end
|
145
|
-
|
146
|
-
it 'loads an aggregate with multiple associations' do
|
147
|
-
jane = repo.aggregate(:posts, :labels).where(name: 'Jane').one
|
148
|
-
|
149
|
-
expect(jane.posts.size).to be(1)
|
150
|
-
expect(jane.posts.first.title).to eql('Hello From Jane')
|
151
|
-
|
152
|
-
expect(jane.labels.size).to be(2)
|
153
|
-
expect(jane.labels[0].name).to eql('red')
|
154
|
-
expect(jane.labels[1].name).to eql('blue')
|
155
|
-
end
|
156
|
-
|
157
|
-
it 'loads children and its parents via wrap_parent' do
|
158
|
-
posts = repo.posts.wrap_parent(author: repo.users)
|
159
|
-
|
160
|
-
label = repo.labels.combine(many: { posts: posts }).first
|
161
|
-
|
162
|
-
expect(label.name).to eql('red')
|
163
|
-
expect(label.posts.size).to be(1)
|
164
|
-
expect(label.posts[0].title).to eql('Hello From Jane')
|
165
|
-
expect(label.posts[0].author.name).to eql('Jane')
|
166
|
-
end
|
167
|
-
|
168
|
-
it 'loads children and its parents via wrap and association name' do
|
169
|
-
label = repo.labels.combine(many: { posts: repo.posts.wrap(:author) }).first
|
170
|
-
|
171
|
-
expect(label.name).to eql('red')
|
172
|
-
expect(label.posts.size).to be(1)
|
173
|
-
expect(label.posts[0].title).to eql('Hello From Jane')
|
174
|
-
expect(label.posts[0].author.name).to eql('Jane')
|
175
|
-
end
|
176
|
-
|
177
|
-
it 'loads a parent via custom fks' do
|
178
|
-
post = repo.posts.combine(:author).where(title: 'Hello From Jane').one
|
179
|
-
|
180
|
-
expect(post.title).to eql('Hello From Jane')
|
181
|
-
expect(post.author.name).to eql('Jane')
|
182
|
-
end
|
183
|
-
|
184
|
-
it 'loads aggregate through many-to-many via custom options' do
|
185
|
-
post = repo.posts
|
186
|
-
.combine_children(many: repo.labels)
|
187
|
-
.where(title: 'Hello From Jane')
|
188
|
-
.one
|
189
|
-
|
190
|
-
expect(post.title).to eql('Hello From Jane')
|
191
|
-
expect(post.labels.size).to be(2)
|
192
|
-
expect(post.labels.map(&:name)).to eql(%w(red blue))
|
193
|
-
end
|
194
|
-
|
195
|
-
it 'loads aggregate through many-to-many association' do
|
196
|
-
post = repo.posts.combine(:labels).where(title: 'Hello From Jane').one
|
197
|
-
|
198
|
-
expect(post.title).to eql('Hello From Jane')
|
199
|
-
expect(post.labels.size).to be(2)
|
200
|
-
expect(post.labels.map(&:name)).to eql(%w(red blue))
|
201
|
-
end
|
202
|
-
|
203
|
-
it 'loads multiple child relations' do
|
204
|
-
user = repo.users.combine_children(many: [repo.posts, repo.tasks]).where(name: 'Jane').one
|
205
|
-
|
206
|
-
expect(user.name).to eql('Jane')
|
207
|
-
expect(user.posts.size).to be(1)
|
208
|
-
expect(user.posts[0].title).to eql('Hello From Jane')
|
209
|
-
expect(user.tasks.size).to be(1)
|
210
|
-
expect(user.tasks[0].title).to eql('Jane Task')
|
211
|
-
end
|
212
|
-
|
213
|
-
it 'loads multiple parent relations' do
|
214
|
-
post_label = repo.posts_labels.combine_parents(one: [repo.posts]).first
|
215
|
-
|
216
|
-
expect(post_label.post.title).to eql('Hello From Jane')
|
217
|
-
end
|
218
|
-
|
219
|
-
context 'not common naming conventions' do
|
220
|
-
it 'still loads nested relations' do
|
221
|
-
comments = comments_repo.comments_with_likes.to_a
|
222
|
-
|
223
|
-
expect(comments.size).to be(2)
|
224
|
-
expect(comments[0].author).to eql('Jane')
|
225
|
-
expect(comments[0].likes[0].author).to eql('Joe')
|
226
|
-
expect(comments[0].likes[1].author).to eql('Anonymous')
|
227
|
-
expect(comments[1].author).to eql('Joe')
|
228
|
-
expect(comments[1].likes[0].author).to eql('Jane')
|
229
|
-
end
|
230
|
-
|
231
|
-
it 'loads nested relations by association name' do
|
232
|
-
comments = comments_repo.comments_with_emotions.to_a
|
233
|
-
|
234
|
-
expect(comments.size).to be(2)
|
235
|
-
expect(comments[0].emotions[0].author).to eql('Joe')
|
236
|
-
expect(comments[0].emotions[1].author).to eql('Anonymous')
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
describe 'projecting virtual attributes' do
|
241
|
-
before do
|
242
|
-
ROM::Repository::StructBuilder.cache.clear
|
243
|
-
ROM::Repository::MapperBuilder.cache.clear
|
244
|
-
end
|
245
|
-
|
246
|
-
shared_context 'auto-mapping' do
|
247
|
-
it 'loads auto-mapped structs' do
|
248
|
-
user = repo.users.
|
249
|
-
inner_join(:posts, author_id: :id).
|
250
|
-
select_group { [id.qualified, name.qualified] }.
|
251
|
-
select_append { int::count(:posts).as(:post_count) }.
|
252
|
-
having { count(id.qualified) >= 1 }.
|
253
|
-
first
|
254
|
-
|
255
|
-
expect(user.id).to be(1)
|
256
|
-
expect(user.name).to eql('Jane')
|
257
|
-
expect(user.post_count).to be(1)
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
context 'with default namespace' do
|
262
|
-
include_context 'auto-mapping'
|
263
|
-
end
|
264
|
-
|
265
|
-
context 'with custom struct namespace' do
|
266
|
-
before do
|
267
|
-
repo_class.struct_namespace(Test)
|
268
|
-
end
|
269
|
-
|
270
|
-
include_context 'auto-mapping'
|
271
|
-
|
272
|
-
it 'uses custom namespace' do
|
273
|
-
expect(Test.const_defined?(:User)).to be(false)
|
274
|
-
user = repo.users.limit(1).one!
|
275
|
-
|
276
|
-
expect(user.name).to eql('Jane')
|
277
|
-
expect(user.class).to be < Test::User
|
278
|
-
expect(user.class.name).to eql(Test::User.name)
|
279
|
-
end
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
describe 'projecting aliased attributes' do
|
284
|
-
it 'loads auto-mapped structs' do
|
285
|
-
user = repo.users.select { [id.aliased(:userId), name.aliased(:userName)] }.first
|
286
|
-
|
287
|
-
expect(user.userId).to be(1)
|
288
|
-
expect(user.userName).to eql('Jane')
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
|
-
context 'with a table without columns' do
|
293
|
-
before { conn.create_table(:dummy) unless conn.table_exists?(:dummy) }
|
294
|
-
|
295
|
-
it 'does not fail with a weird error when a relation does not have attributes' do
|
296
|
-
configuration.relation(:dummy) { schema(infer: true) }
|
297
|
-
|
298
|
-
repo = Class.new(ROM::Repository[:dummy]).new(rom)
|
299
|
-
expect(repo.dummy.to_a).to eql([])
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
describe 'mapping without structs' do
|
304
|
-
shared_context 'plain hash mapping' do
|
305
|
-
describe '#one' do
|
306
|
-
it 'returns a hash' do
|
307
|
-
expect(repo.users.limit(1).one).to eql(id: 1, name: 'Jane')
|
308
|
-
end
|
309
|
-
|
310
|
-
it 'returns a nested hash for an aggregate' do
|
311
|
-
expect(repo.aggregate(:posts).limit(1).one).
|
312
|
-
to eql(id: 1, name: 'Jane', posts: [{ id: 1, author_id: 1, title: 'Hello From Jane', body: 'Jane Post'}])
|
313
|
-
end
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
context 'with auto_struct disabled upon initialization' do
|
318
|
-
subject(:repo) do
|
319
|
-
repo_class.new(rom, auto_struct: false)
|
320
|
-
end
|
321
|
-
|
322
|
-
include_context 'plain hash mapping'
|
323
|
-
end
|
324
|
-
|
325
|
-
context 'with auto_struct disabled at the class level' do
|
326
|
-
before do
|
327
|
-
repo_class.auto_struct(false)
|
328
|
-
end
|
329
|
-
|
330
|
-
include_context 'plain hash mapping'
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
describe 'using custom mappers along with auto-mapping' do
|
335
|
-
before do
|
336
|
-
configuration.mappers do
|
337
|
-
define(:users) do
|
338
|
-
register_as :embed_address
|
339
|
-
|
340
|
-
def call(rel)
|
341
|
-
rel.map { |tuple| Hash(tuple).merge(mapped: true) }
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
define(:posts) do
|
346
|
-
register_as :nested_mapper
|
347
|
-
|
348
|
-
def call(rel)
|
349
|
-
rel.map { |tuple| Hash(tuple).tap { |h| h[:title] = h[:title].upcase } }
|
350
|
-
end
|
351
|
-
end
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
it 'auto-maps and applies a custom mapper' do
|
356
|
-
jane = repo.users.combine(:posts).map_with(:embed_address, auto_map: true).to_a.first
|
357
|
-
|
358
|
-
expect(jane).
|
359
|
-
to eql(id:1, name: 'Jane', mapped: true, posts: [
|
360
|
-
{ id: 1, author_id: 1, title: 'Hello From Jane', body: 'Jane Post' }
|
361
|
-
])
|
362
|
-
end
|
363
|
-
|
364
|
-
it 'applies a custom mapper inside #node' do
|
365
|
-
jane = repo.aggregate(:posts).node(:posts) { |posts| posts.as(:nested_mapper, auto_map: true) }.to_a.first
|
366
|
-
|
367
|
-
expect(jane).to be_a ROM::Struct
|
368
|
-
|
369
|
-
expect(jane.to_h).
|
370
|
-
to eql(id:1, name: 'Jane', posts: [
|
371
|
-
{ id: 1, author_id: 1, title: 'HELLO FROM JANE', body: 'Jane Post' }
|
372
|
-
])
|
373
|
-
end
|
374
|
-
end
|
375
|
-
|
376
|
-
describe 'using a custom model for a node' do
|
377
|
-
before do
|
378
|
-
class Test::Post < OpenStruct; end
|
379
|
-
end
|
380
|
-
|
381
|
-
it 'uses provided model for the member type' do
|
382
|
-
jane = repo.users.combine(many: repo.posts.as(Test::Post)).where(name: 'Jane').one
|
383
|
-
|
384
|
-
expect(jane.name).to eql('Jane')
|
385
|
-
expect(jane.posts.size).to be(1)
|
386
|
-
expect(jane.posts[0]).to be_instance_of(Test::Post)
|
387
|
-
expect(jane.posts[0].title).to eql('Hello From Jane')
|
388
|
-
expect(jane.posts[0].body).to eql('Jane Post')
|
389
|
-
end
|
390
|
-
|
391
|
-
it 'uses provided model for the attribute type' do
|
392
|
-
jane = repo.users.combine(one: repo.posts.as(Test::Post)).where(name: 'Jane').one
|
393
|
-
|
394
|
-
expect(jane.name).to eql('Jane')
|
395
|
-
expect(jane.post).to be_instance_of(Test::Post)
|
396
|
-
expect(jane.post.title).to eql('Hello From Jane')
|
397
|
-
expect(jane.post.body).to eql('Jane Post')
|
398
|
-
end
|
399
|
-
end
|
400
|
-
|
401
|
-
it 'loads structs using plain SQL' do
|
402
|
-
jane = repo.users.read("SELECT name FROM users WHERE name = 'Jane'").one
|
403
|
-
|
404
|
-
expect(jane.name).to eql('Jane')
|
405
|
-
end
|
406
|
-
end
|