rom-repository 0.2.0 → 0.3.0
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/.gitignore +1 -0
- data/.travis.yml +5 -5
- data/CHANGELOG.md +24 -0
- data/Gemfile +21 -5
- data/README.md +6 -110
- data/lib/rom/repository/changeset/create.rb +26 -0
- data/lib/rom/repository/changeset/pipe.rb +40 -0
- data/lib/rom/repository/changeset/update.rb +82 -0
- data/lib/rom/repository/changeset.rb +99 -0
- data/lib/rom/repository/class_interface.rb +142 -0
- data/lib/rom/repository/command_compiler.rb +214 -0
- data/lib/rom/repository/command_proxy.rb +22 -0
- data/lib/rom/repository/header_builder.rb +13 -16
- data/lib/rom/repository/mapper_builder.rb +7 -14
- data/lib/rom/repository/{loading_proxy → relation_proxy}/wrap.rb +7 -7
- data/lib/rom/repository/relation_proxy.rb +225 -0
- data/lib/rom/repository/root.rb +110 -0
- data/lib/rom/repository/struct_attributes.rb +46 -0
- data/lib/rom/repository/struct_builder.rb +31 -14
- data/lib/rom/repository/version.rb +1 -1
- data/lib/rom/repository.rb +192 -31
- data/lib/rom/struct.rb +13 -8
- data/rom-repository.gemspec +9 -10
- data/spec/integration/changeset_spec.rb +86 -0
- data/spec/integration/command_macros_spec.rb +175 -0
- data/spec/integration/command_spec.rb +224 -0
- data/spec/integration/multi_adapter_spec.rb +3 -3
- data/spec/integration/repository_spec.rb +97 -2
- data/spec/integration/root_repository_spec.rb +88 -0
- data/spec/shared/database.rb +47 -3
- data/spec/shared/mappers.rb +35 -0
- data/spec/shared/models.rb +41 -0
- data/spec/shared/plugins.rb +66 -0
- data/spec/shared/relations.rb +76 -0
- data/spec/shared/repo.rb +38 -17
- data/spec/shared/seeds.rb +19 -0
- data/spec/spec_helper.rb +4 -1
- data/spec/support/mapper_registry.rb +1 -3
- data/spec/unit/changeset_spec.rb +58 -0
- data/spec/unit/header_builder_spec.rb +34 -35
- data/spec/unit/relation_proxy_spec.rb +170 -0
- data/spec/unit/sql/relation_spec.rb +5 -5
- data/spec/unit/struct_builder_spec.rb +7 -4
- data/spec/unit/struct_spec.rb +22 -0
- metadata +38 -41
- data/lib/rom/plugins/relation/key_inference.rb +0 -31
- data/lib/rom/repository/loading_proxy/combine.rb +0 -158
- data/lib/rom/repository/loading_proxy.rb +0 -182
- data/spec/unit/loading_proxy_spec.rb +0 -147
@@ -0,0 +1,35 @@
|
|
1
|
+
RSpec.shared_context 'mappers' do
|
2
|
+
let(:users) { rom.relation(:users).mappers[:user] }
|
3
|
+
let(:tasks) { rom.relation(:tasks).mappers[:task] }
|
4
|
+
let(:tags) { rom.relation(:tags).mappers[:tag] }
|
5
|
+
|
6
|
+
before do
|
7
|
+
configuration.mappers do
|
8
|
+
define(:users) do
|
9
|
+
model Test::Models::User
|
10
|
+
register_as :user
|
11
|
+
|
12
|
+
attribute :id
|
13
|
+
attribute :name
|
14
|
+
end
|
15
|
+
|
16
|
+
define(:tasks) do
|
17
|
+
model Test::Models::Task
|
18
|
+
register_as :task
|
19
|
+
|
20
|
+
attribute :id
|
21
|
+
attribute :user_id
|
22
|
+
attribute :title
|
23
|
+
end
|
24
|
+
|
25
|
+
define(:tags) do
|
26
|
+
model Test::Models::Tag
|
27
|
+
register_as :tag
|
28
|
+
|
29
|
+
attribute :id
|
30
|
+
attribute :task_id
|
31
|
+
attribute :name
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
RSpec.shared_context 'models' do
|
2
|
+
let(:user_model) { Test::Models::User }
|
3
|
+
let(:task_model) { Test::Models::Task }
|
4
|
+
let(:tag_model) { Test::Models::Tag }
|
5
|
+
|
6
|
+
before do
|
7
|
+
module Test
|
8
|
+
module Models
|
9
|
+
class User
|
10
|
+
include Dry::Equalizer(:id, :name)
|
11
|
+
|
12
|
+
attr_reader :id, :name
|
13
|
+
|
14
|
+
def initialize(attrs)
|
15
|
+
@id, @name = attrs[:id], attrs[:name]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Task
|
20
|
+
include Dry::Equalizer(:id, :user_id, :title)
|
21
|
+
|
22
|
+
attr_reader :id, :user_id, :title
|
23
|
+
|
24
|
+
def initialize(attrs)
|
25
|
+
@id, @name, @title = attrs[:id], attrs[:name], attrs[:title]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Tag
|
30
|
+
include Dry::Equalizer(:id, :task_id, :name)
|
31
|
+
|
32
|
+
attr_reader :id, :task_id, :name
|
33
|
+
|
34
|
+
def initialize(attrs)
|
35
|
+
@id, @task_id, @name = attrs[:id], attrs[:task_id], attrs[:name]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
RSpec.shared_context 'plugins' do
|
2
|
+
before do
|
3
|
+
module Test
|
4
|
+
class WrappingInput
|
5
|
+
def initialize(input)
|
6
|
+
@input = input || Hash
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module Timestamps
|
11
|
+
class InputWithTimestamp < WrappingInput
|
12
|
+
def [](value)
|
13
|
+
v = @input[value]
|
14
|
+
now = Time.now
|
15
|
+
|
16
|
+
if v[:created_at]
|
17
|
+
v.merge(updated_at: now)
|
18
|
+
else
|
19
|
+
v.merge(created_at: now, updated_at: now)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module ClassInterface
|
25
|
+
def build(relation, options = {})
|
26
|
+
super(relation, options.merge(input: InputWithTimestamp.new(input)))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.included(klass)
|
31
|
+
super
|
32
|
+
|
33
|
+
klass.extend ClassInterface
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module UpcaseName
|
38
|
+
class UpcaseNameInput < WrappingInput
|
39
|
+
def [](value)
|
40
|
+
v = @input[value]
|
41
|
+
v.merge(name: value.fetch(:name).upcase)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module ClassInterface
|
46
|
+
def build(relation, options = {})
|
47
|
+
super(relation, options.merge(input: UpcaseNameInput.new(options.fetch(:input))))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.included(klass)
|
52
|
+
super
|
53
|
+
|
54
|
+
klass.extend ClassInterface
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
ROM.plugins do
|
60
|
+
adapter :sql do
|
61
|
+
register :timestamps, Test::Timestamps, type: :command
|
62
|
+
register :upcase_name, Test::UpcaseName, type: :command
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/spec/shared/relations.rb
CHANGED
@@ -2,9 +2,31 @@ RSpec.shared_context 'relations' do
|
|
2
2
|
let(:users) { rom.relation(:users) }
|
3
3
|
let(:tasks) { rom.relation(:tasks) }
|
4
4
|
let(:tags) { rom.relation(:tags) }
|
5
|
+
let(:posts) { rom.relation(:posts) }
|
6
|
+
let(:books) { rom.relation(:books) }
|
5
7
|
|
6
8
|
before do
|
9
|
+
configuration.relation(:books) do
|
10
|
+
schema(:books) do
|
11
|
+
attribute :id, ROM::SQL::Types::Serial
|
12
|
+
attribute :title, ROM::SQL::Types::String
|
13
|
+
attribute :created_at, ROM::SQL::Types::Time
|
14
|
+
attribute :updated_at, ROM::SQL::Types::Time
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
7
18
|
configuration.relation(:users) do
|
19
|
+
schema(infer: true) do
|
20
|
+
associations do
|
21
|
+
has_many :posts
|
22
|
+
has_many :labels, through: :posts
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def by_name(name)
|
27
|
+
where(name: name)
|
28
|
+
end
|
29
|
+
|
8
30
|
def all
|
9
31
|
select(:id, :name).order(:name, :id)
|
10
32
|
end
|
@@ -15,6 +37,12 @@ RSpec.shared_context 'relations' do
|
|
15
37
|
end
|
16
38
|
|
17
39
|
configuration.relation(:tasks) do
|
40
|
+
schema(infer: true) do
|
41
|
+
associations do
|
42
|
+
belongs_to :user
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
18
46
|
def find(criteria)
|
19
47
|
where(criteria)
|
20
48
|
end
|
@@ -25,5 +53,53 @@ RSpec.shared_context 'relations' do
|
|
25
53
|
end
|
26
54
|
|
27
55
|
configuration.relation(:tags)
|
56
|
+
|
57
|
+
configuration.relation(:labels) do
|
58
|
+
schema(infer: true) do
|
59
|
+
associations do
|
60
|
+
has_many :posts_labels
|
61
|
+
has_many :posts, through: :posts_labels
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
configuration.relation(:posts) do
|
67
|
+
schema(:posts, infer: true) do
|
68
|
+
associations do
|
69
|
+
has_many :labels, through: :posts_labels
|
70
|
+
belongs_to :user, as: :author
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
configuration.relation(:posts_labels) do
|
76
|
+
schema(infer: true) do
|
77
|
+
associations do
|
78
|
+
belongs_to :post
|
79
|
+
belongs_to :label
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
configuration.relation(:comments) do
|
85
|
+
register_as :comments
|
86
|
+
|
87
|
+
schema(:messages, infer: true) do
|
88
|
+
associations do
|
89
|
+
has_many :reactions, relation: :likes
|
90
|
+
has_many :reactions, relation: :likes, as: :emotions
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
configuration.relation(:likes) do
|
96
|
+
register_as :likes
|
97
|
+
|
98
|
+
schema(:reactions, infer: true) do
|
99
|
+
associations do
|
100
|
+
belongs_to :message, relation: :comments
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
28
104
|
end
|
29
105
|
end
|
data/spec/shared/repo.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
RSpec.shared_context('repo') do
|
2
|
+
include_context 'models'
|
3
|
+
include_context 'mappers'
|
4
|
+
|
2
5
|
let(:repo) { repo_class.new(rom) }
|
3
6
|
|
4
7
|
let(:repo_class) do
|
5
|
-
Class.new(ROM::Repository) do
|
6
|
-
relations :
|
8
|
+
Class.new(ROM::Repository[:users]) do
|
9
|
+
relations :tasks, :tags, :posts, :labels
|
7
10
|
|
8
11
|
def find_users(criteria)
|
9
12
|
users.find(criteria)
|
@@ -13,6 +16,26 @@ RSpec.shared_context('repo') do
|
|
13
16
|
users.all
|
14
17
|
end
|
15
18
|
|
19
|
+
def all_users_as_users
|
20
|
+
users.as(:user).all
|
21
|
+
end
|
22
|
+
|
23
|
+
def users_with_tasks
|
24
|
+
aggregate(many: { all_tasks: tasks.for_users })
|
25
|
+
end
|
26
|
+
|
27
|
+
def users_with_tasks_and_tags
|
28
|
+
aggregate(many: { all_tasks: tasks_with_tags(tasks.for_users) })
|
29
|
+
end
|
30
|
+
|
31
|
+
def users_with_task
|
32
|
+
aggregate(one: tasks)
|
33
|
+
end
|
34
|
+
|
35
|
+
def users_with_task_by_title(title)
|
36
|
+
aggregate(one: tasks.find(title: title))
|
37
|
+
end
|
38
|
+
|
16
39
|
def tasks_for_users(users)
|
17
40
|
tasks.for_users(users)
|
18
41
|
end
|
@@ -25,29 +48,27 @@ RSpec.shared_context('repo') do
|
|
25
48
|
tasks.find(id: 2).combine_parents(one: { owner: users })
|
26
49
|
end
|
27
50
|
|
28
|
-
def users_with_tasks
|
29
|
-
users.combine_children(many: { all_tasks: tasks.for_users })
|
30
|
-
end
|
31
|
-
|
32
|
-
def users_with_tasks_and_tags
|
33
|
-
users.combine_children(many: { all_tasks: tasks_with_tags(tasks.for_users) })
|
34
|
-
end
|
35
|
-
|
36
51
|
def tasks_with_tags(tasks = self.tasks)
|
37
52
|
tasks.combine_children(many: tags)
|
38
53
|
end
|
39
54
|
|
40
|
-
def
|
41
|
-
|
55
|
+
def tag_with_wrapped_task
|
56
|
+
tags.wrap_parent(task: tasks)
|
42
57
|
end
|
58
|
+
end
|
59
|
+
end
|
43
60
|
|
44
|
-
|
45
|
-
|
61
|
+
let(:comments_repo) do
|
62
|
+
Class.new(ROM::Repository[:comments]) do
|
63
|
+
relations :likes
|
64
|
+
|
65
|
+
def comments_with_likes
|
66
|
+
aggregate(many: { likes: likes })
|
46
67
|
end
|
47
68
|
|
48
|
-
def
|
49
|
-
|
69
|
+
def comments_with_emotions
|
70
|
+
root.combine(:emotions)
|
50
71
|
end
|
51
|
-
end
|
72
|
+
end.new(rom)
|
52
73
|
end
|
53
74
|
end
|
data/spec/shared/seeds.rb
CHANGED
@@ -7,5 +7,24 @@ RSpec.shared_context 'seeds' do
|
|
7
7
|
task_id = conn[:tasks].insert user_id: jane_id, title: 'Jane Task'
|
8
8
|
|
9
9
|
conn[:tags].insert task_id: task_id, name: 'red'
|
10
|
+
|
11
|
+
jane_post_id = conn[:posts].insert author_id: jane_id, title: 'Hello From Jane', body: 'Jane Post'
|
12
|
+
joe_post_id = conn[:posts].insert author_id: joe_id, title: 'Hello From Joe', body: 'Joe Post'
|
13
|
+
|
14
|
+
red_id = conn[:labels].insert name: 'red'
|
15
|
+
green_id = conn[:labels].insert name: 'green'
|
16
|
+
blue_id = conn[:labels].insert name: 'blue'
|
17
|
+
|
18
|
+
conn[:posts_labels].insert post_id: jane_post_id, label_id: red_id
|
19
|
+
conn[:posts_labels].insert post_id: jane_post_id, label_id: blue_id
|
20
|
+
|
21
|
+
conn[:posts_labels].insert post_id: joe_post_id, label_id: green_id
|
22
|
+
|
23
|
+
conn[:messages].insert author: 'Jane', body: 'Hello folks'
|
24
|
+
conn[:messages].insert author: 'Joe', body: 'Hello Jane'
|
25
|
+
|
26
|
+
conn[:reactions].insert message_id: 1, author: 'Joe'
|
27
|
+
conn[:reactions].insert message_id: 1, author: 'Anonymous'
|
28
|
+
conn[:reactions].insert message_id: 2, author: 'Jane'
|
10
29
|
end
|
11
30
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
require "bundler"
|
5
5
|
Bundler.setup
|
6
6
|
|
7
|
-
if RUBY_ENGINE == "
|
7
|
+
if RUBY_ENGINE == "ruby" && RUBY_VERSION == '2.3.1'
|
8
8
|
require "codeclimate-test-reporter"
|
9
9
|
CodeClimate::TestReporter.start
|
10
10
|
end
|
@@ -28,6 +28,9 @@ Dir[root.join('shared/*.rb').to_s].each do |f|
|
|
28
28
|
require f
|
29
29
|
end
|
30
30
|
|
31
|
+
require 'rom/support/deprecations'
|
32
|
+
ROM::Deprecations.set_logger!(root.join('../log/deprecations.log'))
|
33
|
+
|
31
34
|
# Namespace holding all objects created during specs
|
32
35
|
module Test
|
33
36
|
def self.remove_constants
|
@@ -0,0 +1,58 @@
|
|
1
|
+
RSpec.describe ROM::Changeset do
|
2
|
+
let(:jane) { { id: 2, name: "Jane" } }
|
3
|
+
let(:relation) { double(ROM::Relation, primary_key: :id) }
|
4
|
+
|
5
|
+
describe '#diff' do
|
6
|
+
it 'returns a hash with changes' do
|
7
|
+
expect(relation).to receive(:fetch).with(2).and_return(jane)
|
8
|
+
|
9
|
+
changeset = ROM::Changeset::Update.new(relation, { name: "Jane Doe" }, primary_key: 2)
|
10
|
+
|
11
|
+
expect(changeset.diff).to eql(name: "Jane Doe")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#diff?' do
|
16
|
+
it 'returns true when data differs from the original tuple' do
|
17
|
+
expect(relation).to receive(:fetch).with(2).and_return(jane)
|
18
|
+
|
19
|
+
changeset = ROM::Changeset::Update.new(relation, { name: "Jane Doe" }, primary_key: 2)
|
20
|
+
|
21
|
+
expect(changeset).to be_diff
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'returns false when data are equal to the original tuple' do
|
25
|
+
expect(relation).to receive(:fetch).with(2).and_return(jane)
|
26
|
+
|
27
|
+
changeset = ROM::Changeset::Update.new(relation, { name: "Jane" }, primary_key: 2)
|
28
|
+
|
29
|
+
expect(changeset).to_not be_diff
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'quacks like a hash' do
|
34
|
+
subject(:changeset) { ROM::Changeset::Create.new(relation, data) }
|
35
|
+
|
36
|
+
let(:data) { instance_double(Hash) }
|
37
|
+
|
38
|
+
it 'delegates to its data hash' do
|
39
|
+
expect(data).to receive(:[]).with(:name).and_return('Jane')
|
40
|
+
|
41
|
+
expect(changeset[:name]).to eql('Jane')
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'maintains its own type' do
|
45
|
+
expect(data).to receive(:merge).with(foo: 'bar').and_return(foo: 'bar')
|
46
|
+
|
47
|
+
new_changeset = changeset.merge(foo: 'bar')
|
48
|
+
|
49
|
+
expect(new_changeset).to be_instance_of(ROM::Changeset::Create)
|
50
|
+
expect(new_changeset.options).to eql(changeset.options)
|
51
|
+
expect(new_changeset.to_h).to eql(foo: 'bar')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'raises NoMethodError when an unknown message was sent' do
|
55
|
+
expect { changeset.not_here }.to raise_error(NoMethodError, /not_here/)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -1,18 +1,25 @@
|
|
1
1
|
RSpec.describe 'header builder', '#call' do
|
2
2
|
subject(:builder) { ROM::Repository::HeaderBuilder.new }
|
3
3
|
|
4
|
-
let(:user_struct)
|
5
|
-
|
6
|
-
|
4
|
+
let(:user_struct) do
|
5
|
+
builder.struct_builder[:users, [:header, [[:attribute, :id], [:attribute, :name]]]]
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:task_struct) do
|
9
|
+
builder.struct_builder[:tasks, [:header, [[:attribute, :user_id], [:attribute, :title]]]]
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:tag_struct) do
|
13
|
+
builder.struct_builder[:tags, [:header, [[:attribute, :user_id], [:attribute, :tag]]]]
|
14
|
+
end
|
7
15
|
|
8
16
|
describe 'with a relation' do
|
9
17
|
let(:ast) do
|
10
|
-
[
|
11
|
-
:
|
12
|
-
|
13
|
-
],
|
14
|
-
|
15
|
-
]
|
18
|
+
[:relation, [
|
19
|
+
:users,
|
20
|
+
{ dataset: :users, combine_name: :users },
|
21
|
+
[:header, [[:attribute, :id], [:attribute, :name]]]
|
22
|
+
]]
|
16
23
|
end
|
17
24
|
|
18
25
|
it 'produces a valid header' do
|
@@ -24,32 +31,25 @@ RSpec.describe 'header builder', '#call' do
|
|
24
31
|
|
25
32
|
describe 'with a graph' do
|
26
33
|
let(:ast) do
|
27
|
-
[
|
28
|
-
:
|
34
|
+
[:relation, [
|
35
|
+
:users,
|
36
|
+
{ dataset: :users, combine_name: :users },
|
37
|
+
[
|
29
38
|
:header, [
|
30
39
|
[:attribute, :id],
|
31
40
|
[:attribute, :name],
|
32
|
-
[
|
33
|
-
:
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
{
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
[:attribute, :user_id],
|
45
|
-
[:attribute, :tag]
|
46
|
-
]
|
47
|
-
],
|
48
|
-
{ base_name: :tags, keys: { id: :user_id }, combine_type: :many }
|
49
|
-
]
|
50
|
-
]
|
51
|
-
],
|
52
|
-
base_name: :users
|
41
|
+
[:relation, [
|
42
|
+
:tasks,
|
43
|
+
{ dataset: :tasks, keys: { id: :user_id }, combine_type: :many, combine_name: :tasks },
|
44
|
+
[:header, [[:attribute, :user_id], [:attribute, :title]]]
|
45
|
+
]],
|
46
|
+
[:relation, [
|
47
|
+
:tags,
|
48
|
+
{ dataset: :tags, keys: { id: :user_id }, combine_type: :many, combine_name: :tags },
|
49
|
+
[:header, [[:attribute, :user_id], [:attribute, :tag]]]
|
50
|
+
]]
|
51
|
+
]]
|
52
|
+
]
|
53
53
|
]
|
54
54
|
end
|
55
55
|
|
@@ -63,9 +63,8 @@ RSpec.describe 'header builder', '#call' do
|
|
63
63
|
header: ROM::Header.coerce([[:user_id], [:tag]], model: tag_struct)]
|
64
64
|
]
|
65
65
|
|
66
|
-
header = ROM::Header.coerce(
|
67
|
-
|
68
|
-
model: builder.struct_builder[:users, [:id, :name, :tasks, :tags]]
|
66
|
+
header = ROM::Header.coerce(attributes,
|
67
|
+
model: builder.struct_builder[:users, ast[1][2]]
|
69
68
|
)
|
70
69
|
|
71
70
|
expect(builder[ast]).to eql(header)
|