Skip to content

Commit

Permalink
Merge pull request #403 from sebasjimenez10/inspect-associations-for-…
Browse files Browse the repository at this point in the history
…computing-type

feat: Use the association options to lookup relationship class
  • Loading branch information
gaorlov authored Nov 22, 2023
2 parents b3f6bda + fcb5fbd commit 17f1399
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

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

## 1.21.1
Expand Down
5 changes: 5 additions & 0 deletions lib/json_api_client/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ def self.compute_type(klass, type_name)
# the type_name is an absolute reference.
return type_name.constantize if type_name.match(/^::/)

# Check the klass association definitions
association_klass_match = klass.associations.find { |a| a.attr_name.to_s.singularize == type_name.underscore }
association_klass = association_klass_match.options[:class] if association_klass_match
return association_klass if association_klass

# Build a list of candidates to search for
candidates = []
klass.name.scan(/::|$/) { candidates.unshift "#{$`}::#{type_name}" }
Expand Down
73 changes: 72 additions & 1 deletion test/unit/association_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,21 @@ class Employee < TestResource
has_one :chief, klass: 'Employee'
end

class AssociationTest < Minitest::Test
module CrossNamespaceTwo
class Nail < TestResource
property :size
end
end

module CrossNamespaceOne
class Hammer < TestResource
property :brand

has_many :nails, class: CrossNamespaceTwo::Nail
end
end

class AssociationTest < Minitest::Test
def test_default_properties_no_changes
stub_request(:post, 'http://example.com/accounts').
with(headers: { content_type: 'application/vnd.api+json', accept: 'application/vnd.api+json' }, body: {
Expand Down Expand Up @@ -1070,4 +1083,62 @@ def test_does_not_load_include_from_dataset
assert_nil(records.first.chief)
end

def test_cross_namespace_resource_references
stub_request(:get, 'http://example.com/hammers?include=nails')
.to_return(
headers: {
content_type: 'application/vnd.api+json'
}, body: {
data: [
{
id: '1',
type: 'hammers',
attributes: {
brand: 'Hardware Store'
},
relationships: {
nails: { data: [{id: '2', type: 'nails'}] }
}
},
{
id: '2',
type: 'hammers',
attributes: {
brand: 'Hardware Store'
},
relationships: {
nails: { data: [{id: '3', type: 'nails'}] }
}
}
],
included: [
{
id: '2',
type: 'nails',
attributes: {
size: 10
}
},
{
id: '3',
type: 'nails',
attributes: {
size: 8
}
}
]
}.to_json)

records = CrossNamespaceOne::Hammer.includes(:nails).to_a

assert_equal(2, records.size)
assert_equal('1', records.first.id)
assert_equal('2', records.second.id)
assert_equal('2', records.first.nails.first.id)
assert_equal('3', records.second.nails.first.id)

assert_equal(1, records.first.nails.size)
assert_equal(1, records.second.nails.size)
end

end

0 comments on commit 17f1399

Please sign in to comment.