Skip to content

Commit 0b20783

Browse files
committed
#299 optional get relationship from dataset
1 parent 90fb6ef commit 0b20783

File tree

3 files changed

+117
-8
lines changed

3 files changed

+117
-8
lines changed

lib/json_api_client/included_data.rb

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@ class IncludedData
44

55
def initialize(result_set, data)
66
record_class = result_set.record_class
7-
grouped_data = data.group_by{|datum| datum["type"]}
8-
@data = grouped_data.inject({}) do |h, (type, records)|
7+
included_set = data.map do |datum|
8+
type = datum["type"]
99
klass = Utils.compute_type(record_class, record_class.key_formatter.unformat(type).singularize.classify)
10-
h[type] = records.map do |datum|
11-
params = klass.parser.parameters_from_resource(datum)
12-
resource = klass.load(params)
13-
resource.last_result_set = result_set
14-
resource
15-
end.index_by(&:id)
10+
params = klass.parser.parameters_from_resource(datum)
11+
resource = klass.load(params)
12+
resource.last_result_set = result_set
13+
resource
14+
end
15+
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)
1619
h
1720
end
1821
end

lib/json_api_client/resource.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class Resource
3434
:route_format,
3535
:request_params_class,
3636
:keep_request_params,
37+
:search_included_in_result_set,
3738
instance_accessor: false
3839
class_attribute :add_defaults_to_changes,
3940
instance_writer: false
@@ -50,6 +51,7 @@ class Resource
5051
self.request_params_class = RequestParams
5152
self.keep_request_params = false
5253
self.add_defaults_to_changes = false
54+
self.search_included_in_result_set = false
5355

5456
#:underscored_key, :camelized_key, :dasherized_key, or custom
5557
self.json_key_format = :underscored_key

test/unit/association_test.rb

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ class UserAccount < TestResource
7474
property :balance
7575
end
7676

77+
class Employee < TestResource
78+
has_one :chief, klass: 'Employee'
79+
end
80+
7781
class AssociationTest < MiniTest::Test
7882

7983
def test_default_properties_no_changes
@@ -765,4 +769,104 @@ def test_nested_create_from_scope
765769
Specified.where(foo_id: 1).create
766770
end
767771

772+
def test_load_include_from_dataset
773+
stub_request(:get, 'http://example.com/employees?include=chief&page[per_page]=2')
774+
.to_return(
775+
headers: {
776+
content_type: 'application/vnd.api+json'
777+
}, body: {
778+
data: [
779+
{
780+
id: '1',
781+
type: 'employees',
782+
attributes: {
783+
name: 'John Doe'
784+
},
785+
relationships: {
786+
chief: {
787+
data: {id: '2', type: 'employees'}
788+
}
789+
}
790+
},
791+
{
792+
id: '2',
793+
attributes: {
794+
name: 'Jane Doe'
795+
},
796+
relationships: {
797+
chief: {
798+
data: {id: '3', type: 'employees'}
799+
}
800+
}
801+
}
802+
],
803+
included: [
804+
{
805+
id: '3',
806+
type: 'employees',
807+
attributes: {
808+
name: 'Richard Reed'
809+
}
810+
}
811+
]
812+
}.to_json)
813+
Employee.search_included_in_result_set = true
814+
records = Employee.includes(:chief).per(2).to_a
815+
assert_equal(2, records.size)
816+
assert_equal('1', records.first.id)
817+
assert_equal('2', records.second.id)
818+
assert_equal('3', records.second.chief.id)
819+
assert_equal('2', records.first.chief.id)
820+
end
821+
822+
def test_does_not_load_include_from_dataset
823+
stub_request(:get, 'http://example.com/employees?include=chief&page[per_page]=2')
824+
.to_return(
825+
headers: {
826+
content_type: 'application/vnd.api+json'
827+
}, body: {
828+
data: [
829+
{
830+
id: '1',
831+
type: 'employees',
832+
attributes: {
833+
name: 'John Doe'
834+
},
835+
relationships: {
836+
chief: {
837+
data: {id: '2', type: 'employees'}
838+
}
839+
}
840+
},
841+
{
842+
id: '2',
843+
attributes: {
844+
name: 'Jane Doe'
845+
},
846+
relationships: {
847+
chief: {
848+
data: {id: '3', type: 'employees'}
849+
}
850+
}
851+
}
852+
],
853+
included: [
854+
{
855+
id: '3',
856+
type: 'employees',
857+
attributes: {
858+
name: 'Richard Reed'
859+
}
860+
}
861+
]
862+
}.to_json)
863+
Employee.search_included_in_result_set = false
864+
records = Employee.includes(:chief).per(2).to_a
865+
assert_equal(2, records.size)
866+
assert_equal('1', records.first.id)
867+
assert_equal('2', records.second.id)
868+
assert_equal('3', records.second.chief.id)
869+
assert_nil(records.first.chief)
870+
end
871+
768872
end

0 commit comments

Comments
 (0)