rom-sql 0.9.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 +1 -1
- data/CHANGELOG.md +32 -0
- data/Gemfile +4 -1
- data/lib/rom/plugins/relation/sql/auto_wrap.rb +1 -3
- data/lib/rom/sql/association.rb +33 -14
- data/lib/rom/sql/association/many_to_many.rb +17 -10
- data/lib/rom/sql/association/many_to_one.rb +29 -13
- data/lib/rom/sql/association/name.rb +12 -4
- data/lib/rom/sql/association/one_to_many.rb +21 -10
- data/lib/rom/sql/commands/create.rb +0 -1
- data/lib/rom/sql/commands/update.rb +1 -49
- data/lib/rom/sql/dsl.rb +29 -0
- data/lib/rom/sql/expression.rb +26 -0
- data/lib/rom/sql/function.rb +23 -0
- data/lib/rom/sql/gateway.rb +24 -9
- data/lib/rom/sql/migration.rb +6 -7
- data/lib/rom/sql/migration/migrator.rb +7 -8
- data/lib/rom/sql/order_dsl.rb +20 -0
- data/lib/rom/sql/plugin/associates.rb +58 -45
- data/lib/rom/sql/plugin/pagination.rb +8 -11
- data/lib/rom/sql/plugins.rb +0 -2
- data/lib/rom/sql/projection_dsl.rb +41 -0
- data/lib/rom/sql/qualified_attribute.rb +2 -2
- data/lib/rom/sql/relation.rb +35 -67
- data/lib/rom/sql/relation/reading.rb +77 -25
- data/lib/rom/sql/restriction_dsl.rb +24 -0
- data/lib/rom/sql/schema.rb +73 -7
- data/lib/rom/sql/schema/associations_dsl.rb +4 -3
- data/lib/rom/sql/schema/dsl.rb +5 -2
- data/lib/rom/sql/schema/inferrer.rb +21 -11
- data/lib/rom/sql/transaction.rb +19 -0
- data/lib/rom/sql/type.rb +76 -0
- data/lib/rom/sql/version.rb +1 -1
- data/rom-sql.gemspec +3 -4
- data/spec/extensions/postgres/inferrer_spec.rb +19 -9
- data/spec/integration/association/many_to_many/custom_fks_spec.rb +73 -0
- data/spec/integration/association/many_to_many/from_view_spec.rb +81 -0
- data/spec/integration/association/many_to_many_spec.rb +2 -2
- data/spec/integration/association/many_to_one/custom_fks_spec.rb +59 -0
- data/spec/integration/association/many_to_one/from_view_spec.rb +74 -0
- data/spec/integration/association/many_to_one/self_ref_spec.rb +51 -0
- data/spec/integration/association/many_to_one_spec.rb +4 -2
- data/spec/integration/association/one_to_many/custom_fks_spec.rb +48 -0
- data/spec/integration/association/one_to_many/from_view_spec.rb +57 -0
- data/spec/integration/association/one_to_many/self_ref_spec.rb +52 -0
- data/spec/integration/association/one_to_many_spec.rb +1 -1
- data/spec/integration/association/one_to_one_spec.rb +1 -1
- data/spec/integration/association/one_to_one_through_spec.rb +2 -2
- data/spec/integration/commands/create_spec.rb +11 -27
- data/spec/integration/commands/update_spec.rb +54 -109
- data/spec/integration/gateway_spec.rb +31 -17
- data/spec/integration/plugins/associates_spec.rb +27 -0
- data/spec/integration/plugins/auto_wrap_spec.rb +8 -8
- data/spec/integration/schema/call_spec.rb +24 -0
- data/spec/integration/schema/prefix_spec.rb +18 -0
- data/spec/integration/schema/qualified_spec.rb +18 -0
- data/spec/integration/schema/rename_spec.rb +23 -0
- data/spec/integration/schema/view_spec.rb +29 -0
- data/spec/integration/schema_inference_spec.rb +31 -14
- data/spec/spec_helper.rb +2 -2
- data/spec/support/helpers.rb +7 -0
- data/spec/unit/gateway_spec.rb +5 -4
- data/spec/unit/projection_dsl_spec.rb +54 -0
- data/spec/unit/relation/dataset_spec.rb +3 -3
- data/spec/unit/relation/distinct_spec.rb +8 -7
- data/spec/unit/relation/exclude_spec.rb +2 -4
- data/spec/unit/relation/having_spec.rb +6 -4
- data/spec/unit/relation/inner_join_spec.rb +47 -2
- data/spec/unit/relation/invert_spec.rb +2 -3
- data/spec/unit/relation/left_join_spec.rb +44 -3
- data/spec/unit/relation/order_spec.rb +40 -0
- data/spec/unit/relation/prefix_spec.rb +2 -0
- data/spec/unit/relation/project_spec.rb +3 -1
- data/spec/unit/relation/qualified_columns_spec.rb +2 -0
- data/spec/unit/relation/rename_spec.rb +2 -0
- data/spec/unit/relation/right_join_spec.rb +59 -0
- data/spec/unit/relation/select_append_spec.rb +21 -0
- data/spec/unit/relation/select_spec.rb +41 -0
- data/spec/unit/relation/where_spec.rb +28 -0
- data/spec/unit/restriction_dsl_spec.rb +34 -0
- metadata +62 -40
- data/lib/rom/plugins/relation/sql/base_view.rb +0 -31
- data/lib/rom/sql/header.rb +0 -61
- data/lib/rom/sql/plugin/assoc_macros.rb +0 -133
- data/lib/rom/sql/plugin/assoc_macros/class_interface.rb +0 -128
- data/spec/integration/read_spec.rb +0 -111
- data/spec/unit/association_errors_spec.rb +0 -19
- data/spec/unit/plugin/assoc_macros/combined_associations_spec.rb +0 -73
- data/spec/unit/plugin/assoc_macros/many_to_many_spec.rb +0 -53
- data/spec/unit/plugin/assoc_macros/many_to_one_spec.rb +0 -61
- data/spec/unit/plugin/assoc_macros/one_to_many_spec.rb +0 -78
- data/spec/unit/plugin/base_view_spec.rb +0 -18
@@ -0,0 +1,81 @@
|
|
1
|
+
RSpec.describe ROM::SQL::Association::ManyToMany, '#call' do
|
2
|
+
subject(:assoc) do
|
3
|
+
relations[:users].associations[:solved_puzzles]
|
4
|
+
end
|
5
|
+
|
6
|
+
include_context 'database setup'
|
7
|
+
|
8
|
+
with_adapters do
|
9
|
+
before do
|
10
|
+
conn.create_table(:puzzles) do
|
11
|
+
primary_key :id
|
12
|
+
column :text, String, null: false
|
13
|
+
column :solved, TrueClass, null: false, default: false
|
14
|
+
end
|
15
|
+
|
16
|
+
conn.create_table(:puzzle_solvers) do
|
17
|
+
foreign_key :user_id, :users, null: false
|
18
|
+
foreign_key :puzzle_id, :puzzles, null: false
|
19
|
+
primary_key [:user_id, :puzzle_id]
|
20
|
+
end
|
21
|
+
|
22
|
+
conf.relation(:puzzles) do
|
23
|
+
schema(infer: true)
|
24
|
+
|
25
|
+
view(:solved, schema) do
|
26
|
+
where(solved: true)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
conf.relation(:puzzle_solvers) do
|
31
|
+
schema(infer: true) do
|
32
|
+
associations do
|
33
|
+
belongs_to :user
|
34
|
+
belongs_to :puzzle
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
conf.relation(:users) do
|
40
|
+
schema(infer: true) do
|
41
|
+
associations do
|
42
|
+
has_many :puzzle_solvers
|
43
|
+
has_many :puzzles, through: :puzzle_solvers
|
44
|
+
has_many :puzzles, through: :puzzle_solvers, as: :solved_puzzles, view: :solved
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
joe_id = relations[:users].insert(name: 'Joe')
|
50
|
+
jane_id = relations[:users].insert(name: 'Jane')
|
51
|
+
|
52
|
+
p1_id = relations[:puzzles].insert(text: 'P1')
|
53
|
+
p2_id = relations[:puzzles].insert(text: 'P2', solved: true)
|
54
|
+
p3_id = relations[:puzzles].insert(text: 'P3')
|
55
|
+
|
56
|
+
relations[:puzzle_solvers].insert(user_id: joe_id, puzzle_id: p2_id)
|
57
|
+
relations[:puzzle_solvers].insert(user_id: jane_id, puzzle_id: p2_id)
|
58
|
+
|
59
|
+
relations[:puzzle_solvers].insert(user_id: joe_id, puzzle_id: p1_id)
|
60
|
+
relations[:puzzle_solvers].insert(user_id: jane_id, puzzle_id: p3_id)
|
61
|
+
end
|
62
|
+
|
63
|
+
after do
|
64
|
+
conn.drop_table?(:puzzle_solvers)
|
65
|
+
conn.drop_table?(:puzzles)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'prepares joined relations using custom FK' do
|
69
|
+
relation = assoc.call(relations).order(:puzzles__text)
|
70
|
+
|
71
|
+
expect(relation.schema.map(&:to_sym)).
|
72
|
+
to eql(%i[puzzles__id puzzles__text puzzles__solved puzzle_solvers__user_id])
|
73
|
+
|
74
|
+
expect(relation.to_a).
|
75
|
+
to eql([
|
76
|
+
{ id: 2, user_id: 1, solved: true, text: 'P2' },
|
77
|
+
{ id: 2, user_id: 2, solved: true, text: 'P2' }
|
78
|
+
])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -109,7 +109,7 @@ RSpec.describe ROM::SQL::Association::ManyToMany do
|
|
109
109
|
it 'prepares joined relations' do
|
110
110
|
relation = assoc.call(container.relations)
|
111
111
|
|
112
|
-
expect(relation.
|
112
|
+
expect(relation.schema.map(&:to_sym)).to eql(%i[tags__id tags__name task_tags__task_id])
|
113
113
|
expect(relation.to_a).to eql([id: 1, name: 'important', task_id: 1])
|
114
114
|
end
|
115
115
|
end
|
@@ -122,7 +122,7 @@ RSpec.describe ROM::SQL::Association::ManyToMany do
|
|
122
122
|
it 'prepares joined relations through other association' do
|
123
123
|
relation = assoc.call(container.relations)
|
124
124
|
|
125
|
-
expect(relation.
|
125
|
+
expect(relation.schema.map(&:to_sym)).to eql(%i[tags__id tags__name tasks__user_id])
|
126
126
|
expect(relation.to_a).to eql([id: 1, name: 'important', user_id: 2])
|
127
127
|
end
|
128
128
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ROM::SQL::Association::ManyToOne, '#call' do
|
4
|
+
let(:assoc_from) { relations[:flights].associations[:from] }
|
5
|
+
let(:assoc_to) { relations[:flights].associations[:to] }
|
6
|
+
|
7
|
+
include_context 'database setup'
|
8
|
+
|
9
|
+
with_adapters do
|
10
|
+
before do
|
11
|
+
conn.create_table(:destinations) do
|
12
|
+
primary_key :id
|
13
|
+
column :name, String, null: false
|
14
|
+
end
|
15
|
+
|
16
|
+
conn.create_table(:flights) do
|
17
|
+
primary_key :id
|
18
|
+
foreign_key :from_id, :destinations, null: false
|
19
|
+
foreign_key :to_id, :destinations, null: false
|
20
|
+
column :code, String, null: false
|
21
|
+
end
|
22
|
+
|
23
|
+
conf.relation(:flights) do
|
24
|
+
schema(infer: true) do
|
25
|
+
associations do
|
26
|
+
belongs_to :destination, as: :from, foreign_key: :from_id
|
27
|
+
belongs_to :destination, as: :to, foreign_key: :to_id
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
from_id = relations[:destinations].insert(name: 'FROM')
|
33
|
+
to_id = relations[:destinations].insert(name: 'TO')
|
34
|
+
|
35
|
+
relations[:flights].insert(code: 'F1', from_id: from_id, to_id: to_id)
|
36
|
+
end
|
37
|
+
|
38
|
+
after do
|
39
|
+
conn.drop_table(:flights)
|
40
|
+
conn.drop_table(:destinations)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'prepares joined relations using correct FKs based on association aliases' do
|
44
|
+
relation = assoc_from.call(relations)
|
45
|
+
|
46
|
+
expect(relation.schema.map(&:to_sym)).
|
47
|
+
to eql(%i(destinations__id destinations__name flights__id___flight_id))
|
48
|
+
|
49
|
+
expect(relation.first).to eql(id: 1, name: 'FROM', flight_id: 1)
|
50
|
+
|
51
|
+
relation = assoc_to.call(relations)
|
52
|
+
|
53
|
+
expect(relation.schema.map(&:to_sym)).
|
54
|
+
to eql(%i(destinations__id destinations__name flights__id___flight_id))
|
55
|
+
|
56
|
+
expect(relation.first).to eql(id: 2, name: 'TO', flight_id: 1)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ROM::SQL::Association::ManyToOne, '#call' do
|
4
|
+
let(:assoc_inter) { relations[:flights].associations[:inter_destination] }
|
5
|
+
let(:assoc_final) { relations[:flights].associations[:final_destination] }
|
6
|
+
|
7
|
+
include_context 'database setup'
|
8
|
+
|
9
|
+
with_adapters do
|
10
|
+
before do
|
11
|
+
conn.create_table(:destinations) do
|
12
|
+
primary_key :id
|
13
|
+
column :name, String, null: false
|
14
|
+
column :intermediate, TrueClass, null: false, default: false
|
15
|
+
end
|
16
|
+
|
17
|
+
conn.create_table(:flights) do
|
18
|
+
primary_key :id
|
19
|
+
foreign_key :destination_id, :destinations, null: false
|
20
|
+
column :code, String, null: false
|
21
|
+
end
|
22
|
+
|
23
|
+
conf.relation(:destinations) do
|
24
|
+
schema(infer: true)
|
25
|
+
|
26
|
+
view(:intermediate, schema) do
|
27
|
+
where(intermediate: true)
|
28
|
+
end
|
29
|
+
|
30
|
+
view(:final, schema) do
|
31
|
+
where(intermediate: false)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
conf.relation(:flights) do
|
36
|
+
schema(infer: true) do
|
37
|
+
associations do
|
38
|
+
belongs_to :destination, as: :inter_destination, view: :intermediate
|
39
|
+
belongs_to :destination, as: :final_destination, view: :final
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
final_id = relations[:destinations].insert(name: 'Final')
|
45
|
+
inter_id = relations[:destinations].insert(name: 'Intermediate', intermediate: true)
|
46
|
+
|
47
|
+
relations[:flights].insert(code: 'F1', destination_id: inter_id)
|
48
|
+
relations[:flights].insert(code: 'F2', destination_id: final_id)
|
49
|
+
end
|
50
|
+
|
51
|
+
after do
|
52
|
+
conn.drop_table(:flights)
|
53
|
+
conn.drop_table(:destinations)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'prepares joined relations using custom view in target relation' do
|
57
|
+
relation = assoc_inter.call(relations)
|
58
|
+
|
59
|
+
expect(relation.schema.map(&:to_sym)).
|
60
|
+
to eql(%i(destinations__id destinations__name destinations__intermediate flights__id___flight_id))
|
61
|
+
|
62
|
+
expect(relation.first).to eql(id: 2, intermediate: true, name: 'Intermediate', flight_id: 1)
|
63
|
+
expect(relation.count).to be(1)
|
64
|
+
|
65
|
+
relation = assoc_final.call(relations)
|
66
|
+
|
67
|
+
expect(relation.schema.map(&:to_sym)).
|
68
|
+
to eql(%i(destinations__id destinations__name destinations__intermediate flights__id___flight_id))
|
69
|
+
|
70
|
+
expect(relation.first).to eql(id: 1, intermediate: false, name: 'Final', flight_id: 2)
|
71
|
+
expect(relation.count).to be(1)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ROM::SQL::Association::OneToMany, '#call' do
|
4
|
+
subject(:assoc) do
|
5
|
+
relations[:categories].associations[:parent]
|
6
|
+
end
|
7
|
+
|
8
|
+
include_context 'database setup'
|
9
|
+
|
10
|
+
with_adapters do
|
11
|
+
before do
|
12
|
+
conn.create_table(:categories) do
|
13
|
+
primary_key :id
|
14
|
+
foreign_key :parent_id, :categories, null: true
|
15
|
+
column :name, String, null: false
|
16
|
+
end
|
17
|
+
|
18
|
+
conf.relation(:categories) do
|
19
|
+
schema(infer: true) do
|
20
|
+
associations do
|
21
|
+
belongs_to :categories, as: :parent, foreign_key: :parent_id
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
p1_id = relations[:categories].insert(name: 'P1')
|
27
|
+
p2_id = relations[:categories].insert(name: 'P2')
|
28
|
+
c1_id = relations[:categories].insert(name: 'C3', parent_id: p2_id)
|
29
|
+
c2_id = relations[:categories].insert(name: 'C4', parent_id: p1_id)
|
30
|
+
c3_id = relations[:categories].insert(name: 'C5', parent_id: p1_id)
|
31
|
+
end
|
32
|
+
|
33
|
+
after do
|
34
|
+
conn.drop_table(:categories)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'prepares joined relations using custom FK for a self-ref association' do
|
38
|
+
relation = assoc.call(relations)
|
39
|
+
|
40
|
+
expect(relation.schema.map(&:to_sym)).
|
41
|
+
to eql(%i[categories__id categories__parent_id categories__name])
|
42
|
+
|
43
|
+
expect(relation.to_a).
|
44
|
+
to eql([
|
45
|
+
{ id: 1, parent_id: nil, name: 'P1' },
|
46
|
+
{ id: 1, parent_id: nil, name: 'P1' },
|
47
|
+
{ id: 2, parent_id: nil, name: 'P2' }
|
48
|
+
])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -43,7 +43,8 @@ RSpec.describe ROM::SQL::Association::ManyToOne, helpers: true do
|
|
43
43
|
it 'prepares joined relations' do
|
44
44
|
relation = assoc.call(container.relations)
|
45
45
|
|
46
|
-
expect(relation.
|
46
|
+
expect(relation.schema.map(&:to_sym))
|
47
|
+
.to eql(%i[users__id users__name tasks__id___task_id])
|
47
48
|
|
48
49
|
expect(relation.where(user_id: 1).one).to eql(id: 1, task_id: 2, name: 'Jane')
|
49
50
|
|
@@ -89,7 +90,8 @@ RSpec.describe ROM::SQL::Association::ManyToOne, helpers: true do
|
|
89
90
|
it 'prepares joined relations' do
|
90
91
|
relation = assoc.call(container.relations)
|
91
92
|
|
92
|
-
expect(relation.
|
93
|
+
expect(relation.schema.map(&:to_sym))
|
94
|
+
.to eql(%i[users__id users__name posts__post_id])
|
93
95
|
|
94
96
|
expect(relation.order(:id).to_a).to eql([
|
95
97
|
{ id: 1, name: 'Jane', post_id: 2 },
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ROM::SQL::Association::OneToMany, '#call' do
|
4
|
+
subject(:assoc) do
|
5
|
+
relations[:users].associations[:solved_puzzles]
|
6
|
+
end
|
7
|
+
|
8
|
+
include_context 'database setup'
|
9
|
+
|
10
|
+
with_adapters do
|
11
|
+
before do
|
12
|
+
conn.create_table(:puzzles) do
|
13
|
+
primary_key :id
|
14
|
+
foreign_key :author_id, :users, null: false
|
15
|
+
foreign_key :solver_id, :users, null: true
|
16
|
+
column :text, String, null: false
|
17
|
+
end
|
18
|
+
|
19
|
+
conf.relation(:users) do
|
20
|
+
schema(infer: true) do
|
21
|
+
associations do
|
22
|
+
has_many :puzzles, as: :created_puzzles, foreign_key: :author_id
|
23
|
+
has_many :puzzles, as: :solved_puzzles, foreign_key: :solver_id
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
joe_id = relations[:users].insert(name: 'Joe')
|
29
|
+
jane_id = relations[:users].insert(name: 'Jane')
|
30
|
+
|
31
|
+
relations[:puzzles].insert(author_id: joe_id, text: 'P1')
|
32
|
+
relations[:puzzles].insert(author_id: joe_id, solver_id: jane_id, text: 'P2')
|
33
|
+
end
|
34
|
+
|
35
|
+
after do
|
36
|
+
conn.drop_table(:puzzles)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'prepares joined relations using custom FK' do
|
40
|
+
relation = assoc.call(relations)
|
41
|
+
|
42
|
+
expect(relation.schema.map(&:to_sym)).
|
43
|
+
to eql(%i[puzzles__id puzzles__author_id puzzles__solver_id puzzles__text])
|
44
|
+
|
45
|
+
expect(relation.first).to eql(id: 2, author_id: 1, solver_id: 2, text: 'P2')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ROM::SQL::Association::OneToMany, '#call' do
|
4
|
+
subject(:assoc) do
|
5
|
+
relations[:users].associations[:solved_puzzles]
|
6
|
+
end
|
7
|
+
|
8
|
+
include_context 'database setup'
|
9
|
+
|
10
|
+
with_adapters do
|
11
|
+
before do
|
12
|
+
conn.create_table(:puzzles) do
|
13
|
+
primary_key :id
|
14
|
+
foreign_key :user_id, :users, null: false
|
15
|
+
column :text, String, null: false
|
16
|
+
column :solved, TrueClass, null: false, default: false
|
17
|
+
end
|
18
|
+
|
19
|
+
conf.relation(:users) do
|
20
|
+
schema(infer: true) do
|
21
|
+
associations do
|
22
|
+
has_many :puzzles
|
23
|
+
has_many :puzzles, as: :solved_puzzles, view: :solved
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
conf.relation(:puzzles) do
|
29
|
+
schema(infer: true)
|
30
|
+
|
31
|
+
view(:solved, schema) do
|
32
|
+
where(solved: true)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
joe_id = relations[:users].insert(name: 'Joe')
|
37
|
+
jane_id = relations[:users].insert(name: 'Jane')
|
38
|
+
|
39
|
+
relations[:puzzles].insert(user_id: joe_id, text: 'P1')
|
40
|
+
relations[:puzzles].insert(user_id: joe_id, solved: true, text: 'P2')
|
41
|
+
end
|
42
|
+
|
43
|
+
after do
|
44
|
+
conn.drop_table(:puzzles)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'prepares joined relations using custom view' do
|
48
|
+
relation = assoc.call(relations)
|
49
|
+
|
50
|
+
expect(relation.schema.map(&:to_sym)).
|
51
|
+
to eql(%i[puzzles__id puzzles__user_id puzzles__text puzzles__solved])
|
52
|
+
|
53
|
+
expect(relation.count).to be(1)
|
54
|
+
expect(relation.first).to eql(id: 2, user_id: 1, solved: true, text: 'P2')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ROM::SQL::Association::OneToMany, '#call' do
|
4
|
+
subject(:assoc) do
|
5
|
+
relations[:categories].associations[:children]
|
6
|
+
end
|
7
|
+
|
8
|
+
include_context 'database setup'
|
9
|
+
|
10
|
+
with_adapters do
|
11
|
+
before do
|
12
|
+
conn.create_table(:categories) do
|
13
|
+
primary_key :id
|
14
|
+
foreign_key :parent_id, :categories, null: true
|
15
|
+
column :name, String, null: false
|
16
|
+
end
|
17
|
+
|
18
|
+
conf.relation(:categories) do
|
19
|
+
schema(infer: true) do
|
20
|
+
associations do
|
21
|
+
belongs_to :categories, as: :parent, foreign_key: :parent_id
|
22
|
+
has_many :categories, as: :children, foreign_key: :parent_id
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
p1_id = relations[:categories].insert(name: 'P1')
|
28
|
+
p2_id = relations[:categories].insert(name: 'P2')
|
29
|
+
c1_id = relations[:categories].insert(name: 'C3', parent_id: p2_id)
|
30
|
+
c2_id = relations[:categories].insert(name: 'C4', parent_id: p1_id)
|
31
|
+
c3_id = relations[:categories].insert(name: 'C5', parent_id: p1_id)
|
32
|
+
end
|
33
|
+
|
34
|
+
after do
|
35
|
+
conn.drop_table(:categories)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'prepares joined relations using custom FK for a self-ref association' do
|
39
|
+
relation = assoc.call(relations)
|
40
|
+
|
41
|
+
expect(relation.schema.map(&:to_sym)).
|
42
|
+
to eql(%i[categories__id categories__parent_id categories__name])
|
43
|
+
|
44
|
+
expect(relation.to_a).
|
45
|
+
to eql([
|
46
|
+
{ id: 3, parent_id: 2, name: 'C3' },
|
47
|
+
{ id: 4, parent_id: 1, name: 'C4' },
|
48
|
+
{ id: 5, parent_id: 1, name: 'C5' }
|
49
|
+
])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|