rom-repository 1.4.0 → 2.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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,191 +0,0 @@
|
|
1
|
-
RSpec.describe ROM::Repository, '.command' do
|
2
|
-
include_context 'database'
|
3
|
-
include_context 'relations'
|
4
|
-
|
5
|
-
it 'allows configuring a create command' do
|
6
|
-
repo = Class.new(ROM::Repository[:users]) do
|
7
|
-
commands :create
|
8
|
-
end.new(rom)
|
9
|
-
|
10
|
-
user = repo.create(name: 'Jane')
|
11
|
-
|
12
|
-
expect(user.id).to_not be(nil)
|
13
|
-
expect(user.name).to eql('Jane')
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'allows configuring an update and delete commands' do
|
17
|
-
repo = Class.new(ROM::Repository[:users]) do
|
18
|
-
commands :create, update: :by_pk, delete: :by_pk
|
19
|
-
end.new(rom)
|
20
|
-
|
21
|
-
user = repo.create(name: 'Jane')
|
22
|
-
|
23
|
-
repo.update(user.id, name: 'Jane Doe')
|
24
|
-
|
25
|
-
user = repo.users.by_pk(user.id).one
|
26
|
-
|
27
|
-
expect(user.name).to eql('Jane Doe')
|
28
|
-
|
29
|
-
repo.delete(user.id)
|
30
|
-
|
31
|
-
expect(repo.users.by_pk(user.id).one).to be(nil)
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'configures an update command with custom restriction' do
|
35
|
-
repo = Class.new(ROM::Repository[:users]) do
|
36
|
-
commands update: :by_name
|
37
|
-
end.new(rom)
|
38
|
-
|
39
|
-
repo.relations.users.insert(name: 'Jade')
|
40
|
-
|
41
|
-
user = repo.update('Jade', name: 'Jade Doe')
|
42
|
-
expect(user.name).to eql('Jade Doe')
|
43
|
-
|
44
|
-
expect(repo.update('Oops', name: 'Jade')).to be(nil)
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'allows to configure update command without create one' do
|
48
|
-
repo = Class.new(ROM::Repository[:users]) do
|
49
|
-
commands update: :by_pk
|
50
|
-
end.new(rom)
|
51
|
-
|
52
|
-
user = repo.command(create: :users)[name: 'Jane']
|
53
|
-
|
54
|
-
repo.update(user.id, name: 'Jane Doe')
|
55
|
-
|
56
|
-
updated_user = repo.users.by_pk(user.id).one
|
57
|
-
|
58
|
-
expect(updated_user.name).to eql('Jane Doe')
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'allows to configure :delete command without args' do
|
62
|
-
repo = Class.new(ROM::Repository[:users]) do
|
63
|
-
commands :delete
|
64
|
-
end.new(rom)
|
65
|
-
|
66
|
-
repo.users.insert(name: 'Jane')
|
67
|
-
repo.users.insert(name: 'John')
|
68
|
-
|
69
|
-
repo.delete
|
70
|
-
|
71
|
-
expect(repo.users.count).to be_zero
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'allows defining a single command with multiple views' do
|
75
|
-
repo = Class.new(ROM::Repository[:users]) do
|
76
|
-
commands :create, update: [:by_pk, :by_name]
|
77
|
-
end.new(rom)
|
78
|
-
|
79
|
-
user = repo.create(name: 'Jane')
|
80
|
-
|
81
|
-
repo.update_by_pk(user.id, name: 'Jane Doe')
|
82
|
-
user = repo.users.by_pk(user.id).one
|
83
|
-
expect(user.name).to eql('Jane Doe')
|
84
|
-
|
85
|
-
repo.update_by_name(user.name, name: 'Jane')
|
86
|
-
user = repo.users.by_pk(user.id).one
|
87
|
-
expect(user.name).to eql('Jane')
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'uses a mapper built from AST by default' do
|
91
|
-
repo = Class.new(ROM::Repository[:users]) do
|
92
|
-
commands :create
|
93
|
-
end.new(rom)
|
94
|
-
|
95
|
-
user = repo.create(name: 'Jane')
|
96
|
-
|
97
|
-
expect(user).to be_kind_of Dry::Struct
|
98
|
-
|
99
|
-
struct_definition = [:users, [:header, [
|
100
|
-
[:attribute, repo.users.schema[:id]],
|
101
|
-
[:attribute, repo.users.schema[:name]]]]]
|
102
|
-
|
103
|
-
expect(user).to be_an_instance_of ROM::Repository::StructBuilder.cache[struct_definition.hash]
|
104
|
-
end
|
105
|
-
|
106
|
-
describe 'using plugins' do
|
107
|
-
include_context 'plugins'
|
108
|
-
|
109
|
-
before do
|
110
|
-
conn.alter_table :users do
|
111
|
-
add_column :created_at, :timestamp, null: false
|
112
|
-
add_column :updated_at, :timestamp, null: false
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
it 'allows to use plugins in generated commands' do
|
117
|
-
repo = Class.new(ROM::Repository[:users]) do
|
118
|
-
commands :create, update: :by_pk, use: :timestamps
|
119
|
-
end.new(rom)
|
120
|
-
|
121
|
-
user = repo.create(name: 'Jane')
|
122
|
-
expect(user.created_at).to be_within(1).of Time.now
|
123
|
-
expect(user.created_at).to eql(user.updated_at)
|
124
|
-
|
125
|
-
repo.update(user.id, **user, name: 'Jane Doe')
|
126
|
-
updated_user = repo.users.by_pk(user.id).one
|
127
|
-
expect(updated_user.created_at).to eql(user.created_at)
|
128
|
-
expect(updated_user.updated_at).to be > updated_user.created_at
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'allows to use several plugins' do
|
132
|
-
repo = Class.new(ROM::Repository[:users]) do
|
133
|
-
commands :create, use: %i(upcase_name timestamps)
|
134
|
-
end.new(rom)
|
135
|
-
|
136
|
-
user = repo.create(name: 'Jane')
|
137
|
-
expect(user.created_at).to be_within(1).of Time.now
|
138
|
-
expect(user.name).to eql('JANE')
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
describe 'using custom mappers' do
|
143
|
-
before do
|
144
|
-
configuration.mappers do
|
145
|
-
register :users,
|
146
|
-
name_list: -> users { users.map { |u| u[:name] } },
|
147
|
-
id_list: -> users { users.map { |u| u[:id] } }
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
it 'allows to use named mapper in commands' do
|
152
|
-
repo = Class.new(ROM::Repository[:users]).new(rom)
|
153
|
-
|
154
|
-
name = repo.command(create: :users, mapper: :name_list).call(name: 'Jane')
|
155
|
-
|
156
|
-
expect(name).to eql('Jane')
|
157
|
-
end
|
158
|
-
|
159
|
-
it 'caches command pipeline using mapper option' do
|
160
|
-
repo = Class.new(ROM::Repository[:users]).new(rom)
|
161
|
-
|
162
|
-
c1 = repo.command(create: :users, mapper: :name_list)
|
163
|
-
c2 = repo.command(create: :users, mapper: :name_list)
|
164
|
-
c3 = repo.command(create: :users, mapper: :id_list)
|
165
|
-
|
166
|
-
name = c1.call(name: 'Jane')
|
167
|
-
id = c3.call(name: 'John')
|
168
|
-
|
169
|
-
expect(c1).to be c2
|
170
|
-
expect(c3).not_to be c1
|
171
|
-
|
172
|
-
expect(name).to eql('Jane')
|
173
|
-
expect(id).to eql(2)
|
174
|
-
end
|
175
|
-
|
176
|
-
it 'allows to set a mapper with a class-level macro' do
|
177
|
-
repo = Class.new(ROM::Repository[:users]) do
|
178
|
-
commands :create, update: :by_pk, delete: :by_pk, mapper: :name_list
|
179
|
-
end.new(rom)
|
180
|
-
|
181
|
-
name = repo.create(name: 'Jane')
|
182
|
-
expect(name).to eql('Jane')
|
183
|
-
|
184
|
-
updated_name = repo.update(1, name: 'Jane Doe')
|
185
|
-
expect(updated_name).to eql('Jane Doe')
|
186
|
-
|
187
|
-
deleted_name = repo.delete(1)
|
188
|
-
expect(deleted_name).to eql('Jane Doe')
|
189
|
-
end
|
190
|
-
end
|
191
|
-
end
|
@@ -1,228 +0,0 @@
|
|
1
|
-
RSpec.describe ROM::Repository, '#command' do
|
2
|
-
include_context 'database'
|
3
|
-
include_context 'relations'
|
4
|
-
include_context 'repo'
|
5
|
-
|
6
|
-
context 'accessing custom command from the registry' do
|
7
|
-
before do
|
8
|
-
configuration.commands(:users) do
|
9
|
-
define(:upsert, type: ROM::SQL::Commands::Create)
|
10
|
-
define(:create)
|
11
|
-
end
|
12
|
-
|
13
|
-
configuration.commands(:tasks) do
|
14
|
-
define(:create)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'returns registered command' do
|
19
|
-
expect(repo.command(:users).upsert).to be(rom.command(:users).upsert)
|
20
|
-
expect(repo.command(:users)[:upsert]).to be(rom.command(:users).upsert)
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'exposes command builder DSL' do
|
24
|
-
command = repo.command.create(user: :users) { |user| user.create(:tasks) }
|
25
|
-
|
26
|
-
expect(command).to be_instance_of(ROM::Command::Graph)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
context ':create' do
|
31
|
-
it 'builds Create command for a relation' do
|
32
|
-
create_user = repo.command(create: :users)
|
33
|
-
|
34
|
-
user = create_user.call(name: 'Jane Doe')
|
35
|
-
|
36
|
-
expect(user.id).to_not be(nil)
|
37
|
-
expect(user.name).to eql('Jane Doe')
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'uses input_schema for command input' do
|
41
|
-
create_user = repo.command(create: :users)
|
42
|
-
expect(create_user.input).to eql(repo.users.input_schema)
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'caches commands' do
|
46
|
-
create_user = -> { repo.command(create: :users) }
|
47
|
-
|
48
|
-
expect(create_user.()).to be(create_user.())
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'builds Create command for a relation graph with one-to-one' do
|
52
|
-
create_user = repo.command(
|
53
|
-
:create,
|
54
|
-
repo.users.combine_children(one: repo.tasks)
|
55
|
-
)
|
56
|
-
|
57
|
-
user = create_user.call(name: 'Jane Doe', task: { title: 'Task one' })
|
58
|
-
|
59
|
-
expect(user.id).to_not be(nil)
|
60
|
-
expect(user.name).to eql('Jane Doe')
|
61
|
-
expect(user.task.title).to eql('Task one')
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'builds Create command for a deeply nested relation graph' do
|
65
|
-
create_user = repo.command(
|
66
|
-
:create,
|
67
|
-
repo.users.combine_children(one: repo.tasks.combine_children(many: repo.tags))
|
68
|
-
)
|
69
|
-
|
70
|
-
user = create_user.call(
|
71
|
-
name: 'Jane Doe', task: { title: 'Task one', tags: [{ name: 'red' }] }
|
72
|
-
)
|
73
|
-
|
74
|
-
expect(user.id).to_not be(nil)
|
75
|
-
expect(user.name).to eql('Jane Doe')
|
76
|
-
expect(user.task.title).to eql('Task one')
|
77
|
-
expect(user.task.tags).to be_instance_of(Array)
|
78
|
-
expect(user.task.tags.first.name).to eql('red')
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'builds Create command for a relation graph with one-to-many' do
|
82
|
-
create_user = repo.command(
|
83
|
-
:create,
|
84
|
-
repo.users.combine_children(many: repo.tasks)
|
85
|
-
)
|
86
|
-
|
87
|
-
user = create_user.call(name: 'Jane Doe', tasks: [{ title: 'Task one' }])
|
88
|
-
|
89
|
-
expect(user.id).to_not be(nil)
|
90
|
-
expect(user.name).to eql('Jane Doe')
|
91
|
-
expect(user.tasks).to be_instance_of(Array)
|
92
|
-
expect(user.tasks.first.title).to eql('Task one')
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'builds Create command for a relation graph with one-to-many with aliased association' do
|
96
|
-
create_user = repo.command(:create, repo.users.combine(:aliased_posts))
|
97
|
-
|
98
|
-
user = create_user.call(name: 'Jane Doe', aliased_posts: [{ title: 'Post one' }, { title: 'Post two' }])
|
99
|
-
|
100
|
-
expect(user.id).to_not be(nil)
|
101
|
-
expect(user.name).to eql('Jane Doe')
|
102
|
-
expect(user.aliased_posts.size).to be(2)
|
103
|
-
end
|
104
|
-
|
105
|
-
it 'builds Create command for a deeply nested graph with one-to-many' do
|
106
|
-
create_user = repo.command(
|
107
|
-
:create,
|
108
|
-
repo.aggregate(many: repo.tasks.combine_children(many: repo.tags))
|
109
|
-
)
|
110
|
-
|
111
|
-
user = create_user.call(
|
112
|
-
name: 'Jane',
|
113
|
-
tasks: [{ title: 'Task', tags: [{ name: 'red' }]}]
|
114
|
-
)
|
115
|
-
|
116
|
-
expect(user.id).to_not be(nil)
|
117
|
-
expect(user.name).to eql('Jane')
|
118
|
-
expect(user.tasks).to be_instance_of(Array)
|
119
|
-
expect(user.tasks.first.title).to eql('Task')
|
120
|
-
expect(user.tasks.first.tags).to be_instance_of(Array)
|
121
|
-
expect(user.tasks.first.tags.first.name).to eql('red')
|
122
|
-
end
|
123
|
-
|
124
|
-
it 'builds Create command for a deeply nested graph with many-to-one & one-to-many' do
|
125
|
-
create_user = repo.command(
|
126
|
-
:create,
|
127
|
-
repo.aggregate(one: repo.tasks.combine_children(many: repo.tags))
|
128
|
-
)
|
129
|
-
|
130
|
-
user = create_user.call(
|
131
|
-
name: 'Jane', task: { title: 'Task', tags: [{ name: 'red' }, { name: 'blue' }] }
|
132
|
-
)
|
133
|
-
|
134
|
-
expect(user.id).to_not be(nil)
|
135
|
-
expect(user.name).to eql('Jane')
|
136
|
-
expect(user.task.title).to eql('Task')
|
137
|
-
expect(user.task.tags).to be_instance_of(Array)
|
138
|
-
expect(user.task.tags.size).to be(2)
|
139
|
-
expect(user.task.tags[0].name).to eql('red')
|
140
|
-
expect(user.task.tags[1].name).to eql('blue')
|
141
|
-
end
|
142
|
-
|
143
|
-
it 'builds Create command for a deeply nested graph with many-to-one' do
|
144
|
-
create_user = repo.command(
|
145
|
-
:create,
|
146
|
-
repo.aggregate(one: repo.tasks.combine_children(one: repo.tags))
|
147
|
-
)
|
148
|
-
|
149
|
-
user = create_user.call(
|
150
|
-
name: 'Jane', task: { title: 'Task', tag: { name: 'red' } }
|
151
|
-
)
|
152
|
-
|
153
|
-
expect(user.id).to_not be(nil)
|
154
|
-
expect(user.name).to eql('Jane')
|
155
|
-
expect(user.task.id).to_not be(nil)
|
156
|
-
expect(user.task.title).to eql('Task')
|
157
|
-
expect(user.task.tag.id).to_not be(nil)
|
158
|
-
expect(user.task.tag.name).to eql('red')
|
159
|
-
end
|
160
|
-
|
161
|
-
it 'builds Create command for a nested graph with many-to-many' do
|
162
|
-
user = repo.command(:create, repo.users).(name: 'Jane')
|
163
|
-
|
164
|
-
create_post = repo.command(
|
165
|
-
:create, repo.posts.combine_children(many: { labels: repo.labels })
|
166
|
-
)
|
167
|
-
|
168
|
-
post = create_post.call(
|
169
|
-
author_id: user.id, title: 'Jane post', labels: [{ name: 'red' }]
|
170
|
-
)
|
171
|
-
|
172
|
-
expect(post.labels.size).to be(1)
|
173
|
-
end
|
174
|
-
|
175
|
-
context 'relation with a custom dataset name' do
|
176
|
-
it 'allows configuring a create command' do
|
177
|
-
create_comment = comments_repo.command(create: :comments)
|
178
|
-
|
179
|
-
comment = create_comment.(author: 'gerybabooma', body: 'DIS GUY MUST BE A ALIEN OR SUTIN')
|
180
|
-
|
181
|
-
expect(comment.message_id).to eql(1)
|
182
|
-
expect(comment.author).to eql('gerybabooma')
|
183
|
-
expect(comment.body).to eql('DIS GUY MUST BE A ALIEN OR SUTIN')
|
184
|
-
end
|
185
|
-
|
186
|
-
it 'allows configuring a create command with aliased one-to-many' do
|
187
|
-
pending 'custom association names in the input are not yet support'
|
188
|
-
|
189
|
-
create_comment = comments_repo.command(:create, comments_repo.comments.combine(:emotions))
|
190
|
-
|
191
|
-
comment = create_comment.(author: 'Jane',
|
192
|
-
body: 'Hello Joe',
|
193
|
-
emotions: [{ author: 'Joe' }])
|
194
|
-
|
195
|
-
expect(comment.message_id).to eql(1)
|
196
|
-
expect(comment.author).to eql('Jane')
|
197
|
-
expect(comment.body).to eql('Hello Joe')
|
198
|
-
expect(comment.emotions.size).to eql(1)
|
199
|
-
expect(comment.emotions[0].author).to eql('Joe')
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
context ':update' do
|
205
|
-
it 'builds Update command for a relation' do
|
206
|
-
repo.users.insert(id: 3, name: 'Jane')
|
207
|
-
|
208
|
-
update_user = repo.command(:update, repo.users)
|
209
|
-
|
210
|
-
user = update_user.by_pk(3).call(name: 'Jane Doe')
|
211
|
-
|
212
|
-
expect(user.id).to be(3)
|
213
|
-
expect(user.name).to eql('Jane Doe')
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
context ':delete' do
|
218
|
-
it 'builds Delete command for a relation' do
|
219
|
-
repo.users.insert(id: 3, name: 'Jane')
|
220
|
-
|
221
|
-
delete_user = repo.command(:delete, repo.users)
|
222
|
-
|
223
|
-
delete_user.by_pk(3).call
|
224
|
-
|
225
|
-
expect(repo.users.by_pk(3).one).to be(nil)
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
RSpec.describe 'Repository with multi-adapters configuration' do
|
3
|
-
let(:configuration) {
|
4
|
-
ROM::Configuration.new(default: [:sql, DB_URI], memory: [:memory])
|
5
|
-
}
|
6
|
-
|
7
|
-
let(:sql_conn) { configuration.gateways[:default].connection }
|
8
|
-
|
9
|
-
let(:rom) { ROM.container(configuration) }
|
10
|
-
|
11
|
-
let(:users) { rom.relation(:sql_users) }
|
12
|
-
let(:tasks) { rom.relation(:memory_tasks) }
|
13
|
-
|
14
|
-
let(:repo) { Test::Repository.new(rom) }
|
15
|
-
|
16
|
-
before do
|
17
|
-
[:tags, :tasks, :posts, :books, :users, :posts_labels, :labels,
|
18
|
-
:reactions, :messages].each { |table| sql_conn.drop_table?(table) }
|
19
|
-
|
20
|
-
sql_conn.create_table :users do
|
21
|
-
primary_key :id
|
22
|
-
column :name, String
|
23
|
-
end
|
24
|
-
|
25
|
-
module Test
|
26
|
-
class Users < ROM::Relation[:sql]
|
27
|
-
schema(:users, as: :sql_users, infer: true)
|
28
|
-
end
|
29
|
-
|
30
|
-
class Tasks < ROM::Relation[:memory]
|
31
|
-
schema(:tasks, as: :memory_tasks) do
|
32
|
-
attribute :user_id, ROM::Types::Int
|
33
|
-
attribute :title, ROM::Types::String
|
34
|
-
end
|
35
|
-
|
36
|
-
gateway :memory
|
37
|
-
|
38
|
-
use :key_inference
|
39
|
-
|
40
|
-
view(:base, [:user_id, :title]) do
|
41
|
-
self
|
42
|
-
end
|
43
|
-
|
44
|
-
def for_users(users)
|
45
|
-
restrict(user_id: users.pluck(:id))
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
class Repository < ROM::Repository[:sql_users]
|
50
|
-
relations :memory_tasks
|
51
|
-
|
52
|
-
def users_with_tasks(id)
|
53
|
-
aggregate(many: { tasks: memory_tasks }).where(id: id)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
configuration.register_relation(Test::Users)
|
59
|
-
configuration.register_relation(Test::Tasks)
|
60
|
-
|
61
|
-
user_id = configuration.gateways[:default].dataset(:users).insert(name: 'Jane')
|
62
|
-
configuration.gateways[:memory].dataset(:tasks).insert(user_id: user_id, title: 'Jane Task')
|
63
|
-
end
|
64
|
-
|
65
|
-
specify 'ᕕ⁞ ᵒ̌ 〜 ᵒ̌ ⁞ᕗ' do
|
66
|
-
user = repo.users_with_tasks(users.last[:id]).first
|
67
|
-
|
68
|
-
expect(user.name).to eql('Jane')
|
69
|
-
|
70
|
-
expect(user.tasks[0].user_id).to eql(user.id)
|
71
|
-
expect(user.tasks[0].title).to eql('Jane Task')
|
72
|
-
end
|
73
|
-
end
|