Skip to content

Commit 17f1399

Browse files
authored
Merge pull request #403 from sebasjimenez10/inspect-associations-for-computing-type
feat: Use the association options to lookup relationship class
2 parents b3f6bda + fcb5fbd commit 17f1399

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Unreleased
44

5+
- [#403](https://github.com/JsonApiClient/json_api_client/pull/403) - Feature: Use the association options to lookup relationship class
56
- [#406](https://github.com/JsonApiClient/json_api_client/pull/406) - Deep-merge nested `additional_params`
67

78
## 1.21.1

lib/json_api_client/utils.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ def self.compute_type(klass, type_name)
77
# the type_name is an absolute reference.
88
return type_name.constantize if type_name.match(/^::/)
99

10+
# Check the klass association definitions
11+
association_klass_match = klass.associations.find { |a| a.attr_name.to_s.singularize == type_name.underscore }
12+
association_klass = association_klass_match.options[:class] if association_klass_match
13+
return association_klass if association_klass
14+
1015
# Build a list of candidates to search for
1116
candidates = []
1217
klass.name.scan(/::|$/) { candidates.unshift "#{$`}::#{type_name}" }

test/unit/association_test.rb

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,21 @@ class Employee < TestResource
8989
has_one :chief, klass: 'Employee'
9090
end
9191

92-
class AssociationTest < Minitest::Test
92+
module CrossNamespaceTwo
93+
class Nail < TestResource
94+
property :size
95+
end
96+
end
97+
98+
module CrossNamespaceOne
99+
class Hammer < TestResource
100+
property :brand
93101

102+
has_many :nails, class: CrossNamespaceTwo::Nail
103+
end
104+
end
105+
106+
class AssociationTest < Minitest::Test
94107
def test_default_properties_no_changes
95108
stub_request(:post, 'http://example.com/accounts').
96109
with(headers: { content_type: 'application/vnd.api+json', accept: 'application/vnd.api+json' }, body: {
@@ -1070,4 +1083,62 @@ def test_does_not_load_include_from_dataset
10701083
assert_nil(records.first.chief)
10711084
end
10721085

1086+
def test_cross_namespace_resource_references
1087+
stub_request(:get, 'http://example.com/hammers?include=nails')
1088+
.to_return(
1089+
headers: {
1090+
content_type: 'application/vnd.api+json'
1091+
}, body: {
1092+
data: [
1093+
{
1094+
id: '1',
1095+
type: 'hammers',
1096+
attributes: {
1097+
brand: 'Hardware Store'
1098+
},
1099+
relationships: {
1100+
nails: { data: [{id: '2', type: 'nails'}] }
1101+
}
1102+
},
1103+
{
1104+
id: '2',
1105+
type: 'hammers',
1106+
attributes: {
1107+
brand: 'Hardware Store'
1108+
},
1109+
relationships: {
1110+
nails: { data: [{id: '3', type: 'nails'}] }
1111+
}
1112+
}
1113+
],
1114+
included: [
1115+
{
1116+
id: '2',
1117+
type: 'nails',
1118+
attributes: {
1119+
size: 10
1120+
}
1121+
},
1122+
{
1123+
id: '3',
1124+
type: 'nails',
1125+
attributes: {
1126+
size: 8
1127+
}
1128+
}
1129+
]
1130+
}.to_json)
1131+
1132+
records = CrossNamespaceOne::Hammer.includes(:nails).to_a
1133+
1134+
assert_equal(2, records.size)
1135+
assert_equal('1', records.first.id)
1136+
assert_equal('2', records.second.id)
1137+
assert_equal('2', records.first.nails.first.id)
1138+
assert_equal('3', records.second.nails.first.id)
1139+
1140+
assert_equal(1, records.first.nails.size)
1141+
assert_equal(1, records.second.nails.size)
1142+
end
1143+
10731144
end

0 commit comments

Comments
 (0)