rom-sql 1.3.5 → 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 +13 -7
- data/Gemfile +7 -5
- data/lib/rom/plugins/relation/sql/auto_restrictions.rb +11 -17
- data/lib/rom/sql.rb +3 -2
- data/lib/rom/sql/associations.rb +5 -0
- data/lib/rom/sql/associations/core.rb +20 -0
- data/lib/rom/sql/associations/many_to_many.rb +83 -0
- data/lib/rom/sql/associations/many_to_one.rb +55 -0
- data/lib/rom/sql/associations/one_to_many.rb +31 -0
- data/lib/rom/sql/{association → associations}/one_to_one.rb +3 -2
- data/lib/rom/sql/{association → associations}/one_to_one_through.rb +3 -2
- data/lib/rom/sql/associations/self_ref.rb +39 -0
- data/lib/rom/sql/attribute.rb +44 -54
- data/lib/rom/sql/errors.rb +2 -0
- data/lib/rom/sql/extensions/mysql.rb +1 -1
- data/lib/rom/sql/extensions/mysql/attributes_inferrer.rb +10 -0
- data/lib/rom/sql/extensions/postgres.rb +1 -1
- data/lib/rom/sql/extensions/postgres/{inferrer.rb → attributes_inferrer.rb} +4 -4
- data/lib/rom/sql/extensions/postgres/types.rb +9 -19
- data/lib/rom/sql/extensions/sqlite.rb +1 -1
- data/lib/rom/sql/extensions/sqlite/{inferrer.rb → attributes_inferrer.rb} +2 -2
- data/lib/rom/sql/gateway.rb +29 -30
- data/lib/rom/sql/index.rb +13 -0
- data/lib/rom/sql/migration.rb +10 -0
- data/lib/rom/sql/migration/inline_runner.rb +86 -0
- data/lib/rom/sql/migration/migrator.rb +17 -0
- data/lib/rom/sql/migration/schema_diff.rb +177 -0
- data/lib/rom/sql/plugin/associates.rb +11 -45
- data/lib/rom/sql/plugin/pagination.rb +4 -4
- data/lib/rom/sql/relation.rb +22 -42
- data/lib/rom/sql/relation/reading.rb +3 -3
- data/lib/rom/sql/schema.rb +14 -21
- data/lib/rom/sql/schema/associations_dsl.rb +7 -6
- data/lib/rom/sql/schema/attributes_inferrer.rb +164 -0
- data/lib/rom/sql/schema/inferrer.rb +40 -141
- data/lib/rom/sql/type_extensions.rb +44 -0
- data/lib/rom/sql/version.rb +1 -1
- data/lib/rom/sql/wrap.rb +25 -0
- data/rom-sql.gemspec +2 -2
- data/spec/integration/{association → associations}/many_to_many/custom_fks_spec.rb +4 -2
- data/spec/integration/{association → associations}/many_to_many/from_view_spec.rb +2 -2
- data/spec/integration/{association → associations}/many_to_many_spec.rb +25 -30
- data/spec/integration/{association → associations}/many_to_one/custom_fks_spec.rb +5 -3
- data/spec/integration/{association → associations}/many_to_one/from_view_spec.rb +3 -3
- data/spec/integration/{association → associations}/many_to_one/self_ref_spec.rb +2 -2
- data/spec/integration/{association → associations}/many_to_one_spec.rb +20 -38
- data/spec/integration/{association → associations}/one_to_many/custom_fks_spec.rb +4 -2
- data/spec/integration/{association → associations}/one_to_many/from_view_spec.rb +2 -2
- data/spec/integration/{association → associations}/one_to_many/self_ref_spec.rb +2 -2
- data/spec/integration/{association → associations}/one_to_many_spec.rb +24 -11
- data/spec/integration/{association → associations}/one_to_one_spec.rb +13 -9
- data/spec/integration/{association → associations}/one_to_one_through_spec.rb +15 -11
- data/spec/integration/auto_migrations/errors_spec.rb +31 -0
- data/spec/integration/auto_migrations/indexes_spec.rb +109 -0
- data/spec/integration/auto_migrations/managing_columns_spec.rb +156 -0
- data/spec/integration/auto_migrations/postgres/column_types_spec.rb +63 -0
- data/spec/integration/commands/create_spec.rb +2 -4
- data/spec/integration/commands/delete_spec.rb +2 -2
- data/spec/integration/commands/update_spec.rb +2 -0
- data/spec/integration/graph_spec.rb +9 -3
- data/spec/integration/plugins/associates_spec.rb +16 -55
- data/spec/integration/plugins/auto_restrictions_spec.rb +0 -11
- data/spec/integration/relation_schema_spec.rb +49 -25
- data/spec/integration/schema/inferrer/postgres_spec.rb +1 -1
- data/spec/integration/schema/inferrer_spec.rb +7 -18
- data/spec/integration/setup_spec.rb +4 -0
- data/spec/integration/{plugins/auto_wrap_spec.rb → wrap_spec.rb} +13 -36
- data/spec/shared/accounts.rb +4 -0
- data/spec/shared/database_setup.rb +2 -1
- data/spec/shared/notes.rb +2 -0
- data/spec/shared/posts.rb +2 -0
- data/spec/shared/puppies.rb +2 -0
- data/spec/shared/relations.rb +2 -2
- data/spec/shared/users.rb +2 -0
- data/spec/shared/users_and_tasks.rb +4 -0
- data/spec/spec_helper.rb +3 -6
- data/spec/support/helpers.rb +11 -8
- data/spec/support/test_configuration.rb +16 -0
- data/spec/unit/plugin/associates_spec.rb +5 -10
- data/spec/unit/plugin/pagination_spec.rb +9 -9
- data/spec/unit/plugin/timestamp_spec.rb +9 -9
- data/spec/unit/relation/dataset_spec.rb +7 -5
- data/spec/unit/relation/inner_join_spec.rb +2 -15
- data/spec/unit/relation/primary_key_spec.rb +1 -1
- data/spec/unit/schema_spec.rb +6 -4
- metadata +65 -70
- data/lib/rom/plugins/relation/sql/auto_combine.rb +0 -71
- data/lib/rom/plugins/relation/sql/auto_wrap.rb +0 -62
- data/lib/rom/sql/association.rb +0 -103
- data/lib/rom/sql/association/many_to_many.rb +0 -119
- data/lib/rom/sql/association/many_to_one.rb +0 -73
- data/lib/rom/sql/association/name.rb +0 -78
- data/lib/rom/sql/association/one_to_many.rb +0 -60
- data/lib/rom/sql/extensions/mysql/inferrer.rb +0 -10
- data/lib/rom/sql/qualified_attribute.rb +0 -53
- data/lib/rom/sql/schema/dsl.rb +0 -75
- data/spec/unit/association/many_to_many_spec.rb +0 -89
- data/spec/unit/association/many_to_one_spec.rb +0 -81
- data/spec/unit/association/name_spec.rb +0 -68
- data/spec/unit/association/one_to_many_spec.rb +0 -82
- data/spec/unit/association/one_to_one_spec.rb +0 -83
- data/spec/unit/association/one_to_one_through_spec.rb +0 -69
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
module ROM
|
|
2
|
-
module SQL
|
|
3
|
-
class Association
|
|
4
|
-
class OneToMany < Association
|
|
5
|
-
result :many
|
|
6
|
-
|
|
7
|
-
# @api public
|
|
8
|
-
def call(relations, right = relations[target.relation])
|
|
9
|
-
schema = right.schema.qualified
|
|
10
|
-
|
|
11
|
-
relation = right.inner_join(source_table, join_keys(relations))
|
|
12
|
-
|
|
13
|
-
if view
|
|
14
|
-
apply_view(schema, relation)
|
|
15
|
-
else
|
|
16
|
-
schema.(relation)
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# @api public
|
|
21
|
-
def combine_keys(relations)
|
|
22
|
-
Hash[*with_keys(relations)]
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# @api public
|
|
26
|
-
def join_keys(relations)
|
|
27
|
-
with_keys(relations) { |source_key, target_key|
|
|
28
|
-
{ qualify(source_alias, source_key) => qualify(target, target_key) }
|
|
29
|
-
}
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# @api private
|
|
33
|
-
def associate(relations, child, parent)
|
|
34
|
-
pk, fk = join_key_map(relations)
|
|
35
|
-
child.merge(fk => parent.fetch(pk))
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
protected
|
|
39
|
-
|
|
40
|
-
# @api private
|
|
41
|
-
def source_table
|
|
42
|
-
self_ref? ? Sequel.as(source.dataset, source_alias) : source
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# @api private
|
|
46
|
-
def source_alias
|
|
47
|
-
self_ref? ? :"#{source.dataset.to_s[0]}_0" : source
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# @api private
|
|
51
|
-
def with_keys(relations, &block)
|
|
52
|
-
source_key = relations[source.relation].primary_key
|
|
53
|
-
target_key = foreign_key || relations[target.relation].foreign_key(source.relation)
|
|
54
|
-
return [source_key, target_key] unless block
|
|
55
|
-
yield(source_key, target_key)
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
require 'dry/core/cache'
|
|
2
|
-
|
|
3
|
-
module ROM
|
|
4
|
-
module SQL
|
|
5
|
-
# Used as a pair table name + field name.
|
|
6
|
-
# Similar to Sequel::SQL::QualifiedIdentifier but we don't want
|
|
7
|
-
# Sequel types to leak into ROM
|
|
8
|
-
#
|
|
9
|
-
# @api private
|
|
10
|
-
class QualifiedAttribute
|
|
11
|
-
include Dry::Equalizer(:dataset, :attribute)
|
|
12
|
-
|
|
13
|
-
extend Dry::Core::Cache
|
|
14
|
-
|
|
15
|
-
# Dataset (table) name
|
|
16
|
-
#
|
|
17
|
-
# @api private
|
|
18
|
-
attr_reader :dataset
|
|
19
|
-
|
|
20
|
-
# Attribute (field, column) name
|
|
21
|
-
#
|
|
22
|
-
# @api private
|
|
23
|
-
attr_reader :attribute
|
|
24
|
-
|
|
25
|
-
# @api private
|
|
26
|
-
def self.[](*args)
|
|
27
|
-
fetch_or_store(args) { new(*args) }
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# @api private
|
|
31
|
-
def initialize(dataset, attribute)
|
|
32
|
-
@dataset = dataset
|
|
33
|
-
@attribute = attribute
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Used by Sequel for building SQL statements
|
|
37
|
-
#
|
|
38
|
-
# @api private
|
|
39
|
-
def sql_literal_append(ds, sql)
|
|
40
|
-
ds.qualified_identifier_sql_append(sql, dataset, attribute)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Convinient interface for attribute names
|
|
44
|
-
#
|
|
45
|
-
# @return [Symbol]
|
|
46
|
-
#
|
|
47
|
-
# @api private
|
|
48
|
-
def to_sym
|
|
49
|
-
attribute
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
data/lib/rom/sql/schema/dsl.rb
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
require 'rom/sql/attribute'
|
|
2
|
-
require 'rom/sql/schema/inferrer'
|
|
3
|
-
require 'rom/sql/schema/associations_dsl'
|
|
4
|
-
|
|
5
|
-
module ROM
|
|
6
|
-
module SQL
|
|
7
|
-
class Schema < ROM::Schema
|
|
8
|
-
# Extended schema DSL
|
|
9
|
-
#
|
|
10
|
-
# @api private
|
|
11
|
-
class DSL < ROM::Schema::DSL
|
|
12
|
-
attr_reader :associations_dsl
|
|
13
|
-
|
|
14
|
-
# Define associations for a relation
|
|
15
|
-
#
|
|
16
|
-
# @example
|
|
17
|
-
# class Users < ROM::Relation[:sql]
|
|
18
|
-
# schema(infer: true) do
|
|
19
|
-
# associations do
|
|
20
|
-
# has_many :tasks
|
|
21
|
-
# has_many :posts
|
|
22
|
-
# has_many :posts, as: :priority_posts, view: :prioritized
|
|
23
|
-
# belongs_to :account
|
|
24
|
-
# end
|
|
25
|
-
# end
|
|
26
|
-
# end
|
|
27
|
-
#
|
|
28
|
-
# class Posts < ROM::Relation[:sql]
|
|
29
|
-
# schema(infer: true) do
|
|
30
|
-
# associations do
|
|
31
|
-
# belongs_to :users, as: :author
|
|
32
|
-
# end
|
|
33
|
-
# end
|
|
34
|
-
#
|
|
35
|
-
# view(:prioritized) do
|
|
36
|
-
# where { priority <= 3 }
|
|
37
|
-
# end
|
|
38
|
-
# end
|
|
39
|
-
#
|
|
40
|
-
# @return [AssociationDSL]
|
|
41
|
-
#
|
|
42
|
-
# @api public
|
|
43
|
-
def associations(&block)
|
|
44
|
-
@associations_dsl = AssociationsDSL.new(relation, &block)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Return a schema
|
|
48
|
-
#
|
|
49
|
-
# @api private
|
|
50
|
-
def call
|
|
51
|
-
SQL::Schema.define(
|
|
52
|
-
relation, opts.merge(attributes: attributes.values, attr_class: SQL::Attribute)
|
|
53
|
-
)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
private
|
|
57
|
-
|
|
58
|
-
# Return schema opts
|
|
59
|
-
#
|
|
60
|
-
# @return [Hash]
|
|
61
|
-
#
|
|
62
|
-
# @api private
|
|
63
|
-
def opts
|
|
64
|
-
opts = { inferrer: inferrer }
|
|
65
|
-
|
|
66
|
-
if associations_dsl
|
|
67
|
-
{ **opts, associations: associations_dsl.call }
|
|
68
|
-
else
|
|
69
|
-
opts
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::SQL::Association::ManyToMany, helpers: true do
|
|
2
|
-
subject(:assoc) do
|
|
3
|
-
ROM::SQL::Association::ManyToMany.new(source, target, options)
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
let(:options) { { through: :tasks_tags } }
|
|
7
|
-
|
|
8
|
-
let(:tags) { double(:tags, primary_key: :id) }
|
|
9
|
-
let(:tasks) { double(:tasks, primary_key: :id) }
|
|
10
|
-
let(:tasks_tags) { double(:tasks, primary_key: [:task_id, :tag_id]) }
|
|
11
|
-
|
|
12
|
-
let(:source) { :tasks }
|
|
13
|
-
let(:target) { :tags }
|
|
14
|
-
|
|
15
|
-
let(:relations) do
|
|
16
|
-
{ tasks: tasks, tags: tags, tasks_tags: tasks_tags }
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
shared_examples_for 'many-to-many association' do
|
|
20
|
-
describe '#combine_keys' do
|
|
21
|
-
it 'returns a hash with combine keys' do
|
|
22
|
-
expect(tasks_tags).to receive(:foreign_key).with(:tasks).and_return(:tag_id)
|
|
23
|
-
|
|
24
|
-
expect(assoc.combine_keys(relations)).to eql(id: :tag_id)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
describe '#result' do
|
|
30
|
-
it 'is :many' do
|
|
31
|
-
expect(assoc.result).to be(:many)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
describe '#associate' do
|
|
36
|
-
let(:join_assoc) { double(:join_assoc) }
|
|
37
|
-
|
|
38
|
-
let(:source) { :tags }
|
|
39
|
-
let(:target) { :tasks }
|
|
40
|
-
|
|
41
|
-
it 'returns a list of join keys for given child tuples' do
|
|
42
|
-
expect(tasks_tags).to receive(:associations).and_return(assoc.target => join_assoc)
|
|
43
|
-
expect(join_assoc).to receive(:join_key_map).with(relations).and_return([:task_id, :id])
|
|
44
|
-
expect(tasks_tags).to receive(:foreign_key).with(:tags).and_return(:tag_id)
|
|
45
|
-
|
|
46
|
-
task_tuple = { id: 3 }
|
|
47
|
-
tag_tuples = [{ id: 1 }, { id: 2 }]
|
|
48
|
-
|
|
49
|
-
expect(assoc.associate(relations, tag_tuples, task_tuple)).to eql([
|
|
50
|
-
{ tag_id: 1, task_id: 3 }, { tag_id: 2, task_id: 3 }
|
|
51
|
-
])
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
context 'with default names' do
|
|
56
|
-
it_behaves_like 'many-to-many association'
|
|
57
|
-
|
|
58
|
-
describe '#join_keys' do
|
|
59
|
-
it 'returns a hash with combine keys' do
|
|
60
|
-
expect(tasks_tags).to receive(:foreign_key).with(:tasks).and_return(:tag_id)
|
|
61
|
-
|
|
62
|
-
expect(assoc.join_keys(relations)).to eql(
|
|
63
|
-
qualified_attribute(:tasks, :id) => qualified_attribute(:tasks_tags, :tag_id)
|
|
64
|
-
)
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
context 'with custom relation names' do
|
|
70
|
-
let(:source) { assoc_name(:tasks, :user_tasks) }
|
|
71
|
-
let(:target) { assoc_name(:tags, :user_tags) }
|
|
72
|
-
|
|
73
|
-
let(:relations) do
|
|
74
|
-
{ tasks: tasks, tags: tags, tasks_tags: tasks_tags }
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
it_behaves_like 'many-to-many association'
|
|
78
|
-
|
|
79
|
-
describe '#join_keys' do
|
|
80
|
-
it 'returns a hash with combine keys' do
|
|
81
|
-
expect(tasks_tags).to receive(:foreign_key).with(:tasks).and_return(:tag_id)
|
|
82
|
-
|
|
83
|
-
expect(assoc.join_keys(relations)).to eql(
|
|
84
|
-
qualified_attribute(:user_tasks, :id) => qualified_attribute(:tasks_tags, :tag_id)
|
|
85
|
-
)
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::SQL::Association::ManyToOne, helpers: true do
|
|
2
|
-
subject(:assoc) do
|
|
3
|
-
ROM::SQL::Association::ManyToOne.new(source, target, options)
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
let(:options) { {} }
|
|
7
|
-
|
|
8
|
-
let(:users) { double(:users, primary_key: :id) }
|
|
9
|
-
let(:tasks) { double(:tasks) }
|
|
10
|
-
|
|
11
|
-
let(:source) { :tasks }
|
|
12
|
-
let(:target) { :users }
|
|
13
|
-
|
|
14
|
-
let(:relations) do
|
|
15
|
-
{ users: users, tasks: tasks }
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
describe '#result' do
|
|
19
|
-
it 'is :one' do
|
|
20
|
-
expect(assoc.result).to be(:one)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
describe '#associate' do
|
|
25
|
-
it 'returns child tuple with FK set' do
|
|
26
|
-
expect(tasks).to receive(:foreign_key).with(:users).and_return(:user_id)
|
|
27
|
-
|
|
28
|
-
task_tuple = { title: 'Task' }
|
|
29
|
-
user_tuple = { id: 3 }
|
|
30
|
-
|
|
31
|
-
expect(assoc.associate(relations, task_tuple, user_tuple)).to eql(
|
|
32
|
-
user_id: 3, title: 'Task'
|
|
33
|
-
)
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
shared_examples_for 'many-to-many association' do
|
|
38
|
-
describe '#combine_keys' do
|
|
39
|
-
it 'returns a hash with combine keys' do
|
|
40
|
-
expect(tasks).to receive(:foreign_key).with(:users).and_return(:user_id)
|
|
41
|
-
|
|
42
|
-
expect(assoc.combine_keys(relations)).to eql(user_id: :id)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
context 'with default names' do
|
|
48
|
-
it_behaves_like 'many-to-many association'
|
|
49
|
-
|
|
50
|
-
describe '#join_keys' do
|
|
51
|
-
it 'returns a hash with combine keys' do
|
|
52
|
-
expect(tasks).to receive(:foreign_key).with(:users).and_return(:user_id)
|
|
53
|
-
|
|
54
|
-
expect(assoc.join_keys(relations)).to eql(
|
|
55
|
-
qualified_attribute(:tasks, :user_id) => qualified_attribute(:users, :id)
|
|
56
|
-
)
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
context 'with custom relation names' do
|
|
62
|
-
let(:source) { assoc_name(:tasks, :user_tasks) }
|
|
63
|
-
let(:target) { assoc_name(:users, :people) }
|
|
64
|
-
|
|
65
|
-
let(:relations) do
|
|
66
|
-
{ users: users, tasks: tasks }
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
it_behaves_like 'many-to-many association'
|
|
70
|
-
|
|
71
|
-
describe '#join_keys' do
|
|
72
|
-
it 'returns a hash with combine keys' do
|
|
73
|
-
expect(tasks).to receive(:foreign_key).with(:users).and_return(:user_id)
|
|
74
|
-
|
|
75
|
-
expect(assoc.join_keys(relations)).to eql(
|
|
76
|
-
qualified_attribute(:user_tasks, :user_id) => qualified_attribute(:people, :id)
|
|
77
|
-
)
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::SQL::Association::Name do
|
|
2
|
-
describe '.[]' do
|
|
3
|
-
it 'returns a name object from a relation name' do
|
|
4
|
-
rel_name = ROM::Relation::Name[:users]
|
|
5
|
-
assoc_name = ROM::SQL::Association::Name[rel_name]
|
|
6
|
-
|
|
7
|
-
expect(assoc_name).to eql(ROM::SQL::Association::Name.new(rel_name, :users))
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
it 'returns a name object from a relation and a dataset symbols' do
|
|
11
|
-
rel_name = ROM::Relation::Name[:users, :people]
|
|
12
|
-
assoc_name = ROM::SQL::Association::Name[:users, :people]
|
|
13
|
-
|
|
14
|
-
expect(assoc_name).to eql(ROM::SQL::Association::Name.new(rel_name, :people))
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it 'returns a name object from a relation and a dataset symbols and an alias' do
|
|
18
|
-
rel_name = ROM::Relation::Name[:users, :people]
|
|
19
|
-
assoc_name = ROM::SQL::Association::Name[:users, :people, :author]
|
|
20
|
-
|
|
21
|
-
expect(assoc_name).to eql(ROM::SQL::Association::Name.new(rel_name, :author))
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it 'caches names' do
|
|
25
|
-
name = ROM::SQL::Association::Name[:users]
|
|
26
|
-
|
|
27
|
-
expect(name).to be(ROM::SQL::Association::Name[:users])
|
|
28
|
-
|
|
29
|
-
name = ROM::SQL::Association::Name[:users, :people]
|
|
30
|
-
|
|
31
|
-
expect(name).to be(ROM::SQL::Association::Name[:users, :people])
|
|
32
|
-
|
|
33
|
-
name = ROM::SQL::Association::Name[:users, :people, :author]
|
|
34
|
-
|
|
35
|
-
expect(name).to be(ROM::SQL::Association::Name[:users, :people, :author])
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
describe '#aliased?' do
|
|
40
|
-
it 'returns true if a name has an alias' do
|
|
41
|
-
expect(ROM::SQL::Association::Name[:users, :people, :author]).to be_aliased
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it 'returns false if a name has no alias' do
|
|
45
|
-
expect(ROM::SQL::Association::Name[:users, :people]).to_not be_aliased
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
describe '#inspect' do
|
|
50
|
-
it 'includes info about the relation name' do
|
|
51
|
-
expect(ROM::SQL::Association::Name[:users].inspect).to eql(
|
|
52
|
-
"ROM::SQL::Association::Name(users)"
|
|
53
|
-
)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it 'includes info about the relation name and its dataset' do
|
|
57
|
-
expect(ROM::SQL::Association::Name[:users, :people].inspect).to eql(
|
|
58
|
-
"ROM::SQL::Association::Name(users on people)"
|
|
59
|
-
)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it 'includes info about the relation name, its dataset and alias' do
|
|
63
|
-
expect(ROM::SQL::Association::Name[:users, :people, :author].inspect).to eql(
|
|
64
|
-
"ROM::SQL::Association::Name(users on people as author)"
|
|
65
|
-
)
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
RSpec.describe ROM::SQL::Association::OneToMany, helpers: true do
|
|
2
|
-
subject(:assoc) do
|
|
3
|
-
ROM::SQL::Association::OneToMany.new(source, target, options)
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
let(:options) { {} }
|
|
7
|
-
|
|
8
|
-
let(:users) { double(:users, primary_key: :id) }
|
|
9
|
-
let(:tasks) { double(:tasks) }
|
|
10
|
-
|
|
11
|
-
describe '#associate' do
|
|
12
|
-
let(:source) { :users }
|
|
13
|
-
let(:target) { :tasks }
|
|
14
|
-
|
|
15
|
-
let(:relations) do
|
|
16
|
-
{ users: users, tasks: tasks }
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it 'returns child tuple with FK set' do
|
|
20
|
-
expect(tasks).to receive(:foreign_key).with(:users).and_return(:user_id)
|
|
21
|
-
|
|
22
|
-
task_tuple = { title: 'Task' }
|
|
23
|
-
user_tuple = { id: 3 }
|
|
24
|
-
|
|
25
|
-
expect(assoc.associate(relations, task_tuple, user_tuple)).to eql(
|
|
26
|
-
user_id: 3, title: 'Task'
|
|
27
|
-
)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
shared_examples_for 'one-to-many association' do
|
|
32
|
-
describe '#combine_keys' do
|
|
33
|
-
it 'returns a hash with combine keys' do
|
|
34
|
-
expect(tasks).to receive(:foreign_key).with(:users).and_return(:user_id)
|
|
35
|
-
|
|
36
|
-
expect(assoc.combine_keys(relations)).to eql(id: :user_id)
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
context 'with default names' do
|
|
42
|
-
let(:source) { :users }
|
|
43
|
-
let(:target) { :tasks }
|
|
44
|
-
|
|
45
|
-
let(:relations) do
|
|
46
|
-
{ users: users, tasks: tasks }
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it_behaves_like 'one-to-many association'
|
|
50
|
-
|
|
51
|
-
describe '#join_keys' do
|
|
52
|
-
it 'returns a hash with combine keys' do
|
|
53
|
-
expect(tasks).to receive(:foreign_key).with(:users).and_return(:user_id)
|
|
54
|
-
|
|
55
|
-
expect(assoc.join_keys(relations)).to eql(
|
|
56
|
-
qualified_attribute(:users, :id) => qualified_attribute(:tasks, :user_id)
|
|
57
|
-
)
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
context 'with custom relation names' do
|
|
63
|
-
let(:source) { assoc_name(:users, :people) }
|
|
64
|
-
let(:target) { assoc_name(:tasks, :user_tasks) }
|
|
65
|
-
|
|
66
|
-
let(:relations) do
|
|
67
|
-
{ users: users, tasks: tasks }
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
it_behaves_like 'one-to-many association'
|
|
71
|
-
|
|
72
|
-
describe '#join_keys' do
|
|
73
|
-
it 'returns a hash with combine keys' do
|
|
74
|
-
expect(tasks).to receive(:foreign_key).with(:users).and_return(:user_id)
|
|
75
|
-
|
|
76
|
-
expect(assoc.join_keys(relations)).to eql(
|
|
77
|
-
qualified_attribute(:people, :id) => qualified_attribute(:user_tasks, :user_id)
|
|
78
|
-
)
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|