Skip to content

Commit 708adfb

Browse files
matheussilvasantosbazay
authored andcommitted
Fix relationships of included objects (#8)
* Fix parsing of objects that are only in relationships of included If an object was present only in the relationships of an included object and not in the root of the data object or the included object it was not being parsed correctly. * Make original_keys in prepare_object optional * Add spec for prepare_object method * Invoke prepare_class method only when it is needed
1 parent 465553e commit 708adfb

File tree

3 files changed

+67
-9
lines changed

3 files changed

+67
-9
lines changed

lib/json-api-vanilla/parser.rb

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,12 @@ def self.build(hash)
5858

5959
obj_hashes.each do |o_hash|
6060
klass = prepare_class(o_hash, superclass, container)
61-
obj = klass.new
62-
obj.type = o_hash['type']
63-
obj.id = o_hash['id']
64-
if o_hash['attributes']
65-
o_hash['attributes'].each do |key, value|
66-
set_key(obj, key, value, original_keys)
67-
end
68-
end
61+
obj = prepare_object(o_hash, klass, original_keys)
62+
6963
if o_hash['links']
7064
links[obj] = o_hash['links']
7165
end
66+
7267
objects[[obj.type, obj.id]] = obj
7368
end
7469

@@ -82,10 +77,22 @@ def self.build(hash)
8277
if data.is_a?(Array)
8378
# One-to-many relationship.
8479
ref = data.map do |ref_hash|
85-
objects[[ref_hash['type'], ref_hash['id']]]
80+
_ref = objects[[ref_hash['type'], ref_hash['id']]]
81+
82+
if _ref.nil?
83+
klass = prepare_class(ref_hash, superclass, container)
84+
_ref = prepare_object(ref_hash, klass)
85+
end
86+
87+
_ref
8688
end
8789
else
8890
ref = objects[[data['type'], data['id']]]
91+
92+
if ref.nil?
93+
klass = prepare_class(data, superclass, container)
94+
ref = prepare_object(data, klass)
95+
end
8996
end
9097
end
9198

@@ -130,6 +137,18 @@ def self.prepare_class(hash, superclass, container)
130137
klass
131138
end
132139

140+
def self.prepare_object(hash, klass, original_keys = {})
141+
(klass.new).tap do |obj|
142+
obj.type = hash['type']
143+
obj.id = hash['id']
144+
if hash['attributes']
145+
hash['attributes'].each do |key, value|
146+
set_key(obj, key, value, original_keys)
147+
end
148+
end
149+
end
150+
end
151+
133152
def self.generate_object(ruby_name, superclass, container)
134153
klass = Class.new(superclass)
135154
container.const_set(ruby_name, klass)

spec/json-api-vanilla/diff_spec.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
expect(doc.links[doc.data]['self']).to eql("http://example.com/articles")
2121
end
2222

23+
it "should read objects that are only in relationships of included" do
24+
expect(doc.data.first.comments.first.post.id).to eql("42")
25+
end
26+
27+
it "should read objects that are only in relationships of included when it is an array" do
28+
expect(doc.data.first.comments.first.tags[0].id).to eql("42")
29+
end
30+
2331
it "should find objects by type and id" do
2432
expect(doc.find('comments', '5').body).to eql("First!")
2533
end
@@ -114,4 +122,24 @@ class TestClasses
114122
end
115123
end
116124
end
125+
126+
describe '.prepare_object' do
127+
let(:data) do
128+
{
129+
'type' => 'example',
130+
'id' => '1',
131+
'attributes' => {
132+
'name' => 'example name'
133+
}
134+
}
135+
end
136+
let(:klass) { described_class.prepare_class(data, Class.new, Module.new) }
137+
subject { described_class.prepare_object(data, klass) }
138+
139+
it 'creates an object with the attributes mapped' do
140+
expect(subject.type).to eql(data['type'])
141+
expect(subject.id).to eql(data['id'])
142+
expect(subject.name).to eql(data['attributes']['name'])
143+
end
144+
end
117145
end

spec/json-api-vanilla/example.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,17 @@
5656
"relationships": {
5757
"author": {
5858
"data": { "type": "people", "id": "2" }
59+
},
60+
"tags": {
61+
"data": [
62+
{ "type": "tag", "id": "42" }
63+
]
64+
},
65+
"post": {
66+
"data": {
67+
"type": "post",
68+
"id": "42"
69+
}
5970
}
6071
},
6172
"links": {

0 commit comments

Comments
 (0)