diff --git a/CHANGELOG.md b/CHANGELOG.md index 23016f2a..314daa3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- [#349](https://github.com/JsonApiClient/json_api_client/pull/349) - fix resource including for STI objects + ## 1.12.0 - [#345](https://github.com/JsonApiClient/json_api_client/pull/345) - track the real HTTP reason of ApiErrors diff --git a/lib/json_api_client/included_data.rb b/lib/json_api_client/included_data.rb index c62e1f73..0b7063f4 100644 --- a/lib/json_api_client/included_data.rb +++ b/lib/json_api_client/included_data.rb @@ -4,20 +4,30 @@ class IncludedData def initialize(result_set, data) record_class = result_set.record_class - included_set = data.map do |datum| - type = datum["type"] + grouped_data = data.group_by{|datum| datum["type"]} + grouped_included_set = grouped_data.each_with_object({}) do |(type, records), h| klass = Utils.compute_type(record_class, record_class.key_formatter.unformat(type).singularize.classify) - params = klass.parser.parameters_from_resource(datum) - resource = klass.load(params) - resource.last_result_set = result_set - resource + h[type] = records.map do |record| + params = klass.parser.parameters_from_resource(record) + klass.load(params).tap do |resource| + resource.last_result_set = result_set + end + end end - included_set.concat(result_set) if record_class.search_included_in_result_set - @data = included_set.group_by(&:type).inject({}) do |h, (type, resources)| - h[type] = resources.index_by(&:id) - h + if record_class.search_included_in_result_set + # deep_merge overrides the nested Arrays o_O + # {a: [1,2]}.deep_merge(a: [3,4]) # => {a: [3,4]} + grouped_included_set.merge!(result_set.group_by(&:type)) do |_, resources1, resources2| + resources1 + resources2 + end end + + grouped_included_set.each do |type, resources| + grouped_included_set[type] = resources.index_by(&:id) + end + + @data = grouped_included_set end def data_for(method_name, definition) diff --git a/test/unit/association_test.rb b/test/unit/association_test.rb index dcdd4216..65e86e1b 100644 --- a/test/unit/association_test.rb +++ b/test/unit/association_test.rb @@ -854,6 +854,48 @@ def test_get_with_defined_relationship_for_model_with_custom_type assert user.files.first.is_a?(DocumentFile) end + def test_get_with_type_attribute + stub_request(:get, "http://example.com/document_users/1?include=file") + .to_return(headers: {content_type: "application/vnd.api+json"}, body: { + data: [ + { + id: '1', + type: 'document_users', + attributes: { + name: 'John Doe' + }, + relationships: { + file: { + links: { + self: 'http://example.com/document_users/1/relationships/file', + related: 'http://example.com/document_users/1/file' + }, + data: { + id: '2', + type: 'document--files' + } + } + } + } + ], + included: [ + { + id: '2', + type: 'document--files', + attributes: { + type: 'STIDocumentFile', + url: 'http://example.com/downloads/2.pdf' + } + } + ] + }.to_json) + + user = DocumentUser.includes('file').find(1).first + + assert_equal 'STIDocumentFile', user.file.type + assert user.file.is_a?(DocumentFile) + end + def test_load_include_from_dataset stub_request(:get, 'http://example.com/employees?include=chief&page[per_page]=2') .to_return(