Skip to content

Commit c4d8d1c

Browse files
committed
Fix resource including for STI objects
1 parent 424c972 commit c4d8d1c

File tree

2 files changed

+60
-10
lines changed

2 files changed

+60
-10
lines changed

lib/json_api_client/included_data.rb

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,27 @@ class IncludedData
44

55
def initialize(result_set, data)
66
record_class = result_set.record_class
7-
included_set = data.map do |datum|
8-
type = datum["type"]
7+
grouped_data = data.group_by{|datum| datum["type"]}
8+
included_set = grouped_data.each_with_object({}) do |(type, records), h|
99
klass = Utils.compute_type(record_class, record_class.key_formatter.unformat(type).singularize.classify)
10-
params = klass.parser.parameters_from_resource(datum)
11-
resource = klass.load(params)
12-
resource.last_result_set = result_set
13-
resource
10+
h[type] = records.map do |datum|
11+
params = klass.parser.parameters_from_resource(datum)
12+
klass.load(params).tap do |resource|
13+
resource.last_result_set = result_set
14+
end
15+
end
16+
end
17+
18+
if record_class.search_included_in_result_set
19+
# deep_merge overrides the nested Arrays o_O
20+
# {a: [1,2]}.deep_merge(a: [3,4]) # => {a: [3,4]}
21+
included_set.merge!(result_set.group_by(&:type)) do |_, resources1, resources2|
22+
resources1 + resources2
23+
end
1424
end
1525

16-
included_set.concat(result_set) if record_class.search_included_in_result_set
17-
@data = included_set.group_by(&:type).inject({}) do |h, (type, resources)|
18-
h[type] = resources.index_by(&:id)
19-
h
26+
@data = included_set.transform_values! do |resources|
27+
resources.index_by(&:id)
2028
end
2129
end
2230

test/unit/association_test.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,48 @@ def test_get_with_defined_relationship_for_model_with_custom_type
854854
assert user.files.first.is_a?(DocumentFile)
855855
end
856856

857+
def test_get_with_type_attribute
858+
stub_request(:get, "http://example.com/document_users/1?include=file")
859+
.to_return(headers: {content_type: "application/vnd.api+json"}, body: {
860+
data: [
861+
{
862+
id: '1',
863+
type: 'document_users',
864+
attributes: {
865+
name: 'John Doe'
866+
},
867+
relationships: {
868+
file: {
869+
links: {
870+
self: 'http://example.com/document_users/1/relationships/file',
871+
related: 'http://example.com/document_users/1/file'
872+
},
873+
data: {
874+
id: '2',
875+
type: 'document--files'
876+
}
877+
}
878+
}
879+
}
880+
],
881+
included: [
882+
{
883+
id: '2',
884+
type: 'document--files',
885+
attributes: {
886+
type: 'STIDocumentFile',
887+
url: 'http://example.com/downloads/2.pdf'
888+
}
889+
}
890+
]
891+
}.to_json)
892+
893+
user = DocumentUser.includes('file').find(1).first
894+
895+
assert_equal 'STIDocumentFile', user.file.type
896+
assert user.file.is_a?(DocumentFile)
897+
end
898+
857899
def test_load_include_from_dataset
858900
stub_request(:get, 'http://example.com/employees?include=chief&page[per_page]=2')
859901
.to_return(

0 commit comments

Comments
 (0)