Skip to content

Commit f7fa7e8

Browse files
authored
Merge pull request #378 from randyv12/master
feat: Add the ability to override getter for JsonApiClient::Resource id
2 parents 6c8bc2e + 2b02acf commit f7fa7e8

File tree

3 files changed

+185
-1
lines changed

3 files changed

+185
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Changelog
22

33
## Unreleased
4+
- [378](https://github.com/JsonApiClient/json_api_client/pull/378) - Add the ability to create a subclass of JsonApiClient::Resource to have a modified id method
45

56
## 1.21.0
67
- [#395](https://github.com/JsonApiClient/json_api_client/pull/395) - relaxing faraday dependency to anything less than 2.0

lib/json_api_client/included_data.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def initialize(result_set, data)
2424
end
2525

2626
grouped_included_set.each do |type, resources|
27-
grouped_included_set[type] = resources.index_by(&:id)
27+
grouped_included_set[type] = resources.index_by { |resource| resource.attributes[:id] }
2828
end
2929

3030
@data = grouped_included_set

test/unit/integer_id_test.rb

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# frozen_string_literal: true
2+
3+
require 'test_helper'
4+
5+
class BaseResource < JsonApiClient::Resource
6+
self.site = 'http://example.com/'
7+
def id
8+
attributes[:id].to_i if attributes[:id].present?
9+
end
10+
end
11+
12+
class Actor < BaseResource
13+
has_many :movies
14+
end
15+
16+
class Movie < BaseResource
17+
belongs_to :actor, shallow_path: true
18+
has_one :director, shallow_path: true
19+
end
20+
21+
class Director < BaseResource
22+
has_many :movies
23+
end
24+
25+
NUMERIC_ASSERTION = Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.4') ? Fixnum : Integer
26+
27+
class IntegerIdTestAssociationTest < MiniTest::Test
28+
29+
def test_included_document_test_id_from_method_as_integer
30+
stub_request(:get, 'http://example.com/movies/1?include=actor')
31+
.to_return(headers: { content_type: 'application/vnd.api+json',
32+
accept: 'application/vnd.api+json' },
33+
body: {
34+
data: {
35+
id: '1',
36+
type: 'movie',
37+
attributes: {
38+
actor_id: 1,
39+
director_id: 1,
40+
created_at: '2021-04-20T17:27:06-07:00',
41+
updated_at: '2021-04-20T17:27:07-07:00'
42+
},
43+
relationships: {
44+
actor: {
45+
data: {
46+
id: '1',
47+
type: 'actor'
48+
}
49+
},
50+
director: {
51+
data: {
52+
id: '1',
53+
type: 'director'
54+
}
55+
}
56+
}
57+
},
58+
included: [
59+
{
60+
id: '1',
61+
type: 'actor',
62+
attributes: {
63+
name: 'Keanu',
64+
updated_at: '2021-04-22T13:50:19-07:00',
65+
created_at: '2021-04-19T16:20:13-07:00'
66+
}
67+
}
68+
]
69+
}.to_json)
70+
movie = Movie.includes(:actor).find(1).last
71+
assert_equal(NUMERIC_ASSERTION, movie.id.class)
72+
assert_equal(1, movie.id)
73+
assert_equal(String, movie.attributes[:id].class)
74+
assert_equal('1', movie.attributes[:id])
75+
assert_equal(Actor, movie.actor.class)
76+
assert_equal(NUMERIC_ASSERTION, movie.actor.id.class)
77+
assert_equal(1, movie.actor.id)
78+
assert_equal('1', movie.actor.attributes[:id])
79+
assert_equal(movie.actor_id, movie.actor.id)
80+
end
81+
82+
def test_not_included_data_document
83+
stub_request(:get, 'http://example.com/movies/1')
84+
.to_return(headers: { content_type: 'application/vnd.api+json',
85+
accept: 'application/vnd.api+json' },
86+
body: {
87+
data: {
88+
id: '1',
89+
type: 'movie',
90+
attributes: {
91+
actor_id: 1,
92+
created_at: '2021-04-20T17:27:06-07:00',
93+
updated_at: '2021-04-20T17:27:07-07:00'
94+
},
95+
relationships: {
96+
actor: {
97+
data: {
98+
id: '1',
99+
type: 'actor'
100+
},
101+
director: {
102+
data: {
103+
id: '1',
104+
type: 'director'
105+
}
106+
}
107+
}
108+
}
109+
}
110+
}.to_json)
111+
movie = Movie.find(1).last
112+
assert_equal(NUMERIC_ASSERTION, movie.id.class)
113+
assert_equal(1, movie.id)
114+
assert_equal(String, movie.attributes[:id].class)
115+
assert_equal('1', movie.attributes[:id])
116+
assert_nil(movie.actor)
117+
end
118+
119+
def test_not_included_data_document_with_relationships_links
120+
stub_request(:get, 'http://example.com/movies/1')
121+
.to_return(headers: { content_type: 'application/vnd.api+json',
122+
accept: 'application/vnd.api+json' },
123+
body: {
124+
data: {
125+
id: '1',
126+
type: 'movie',
127+
attributes: {
128+
actor_id: 1,
129+
created_at: '2021-04-20T17:27:06-07:00',
130+
updated_at: '2021-04-20T17:27:07-07:00'
131+
},
132+
relationships: {
133+
actor: {
134+
links: {
135+
self: '/movies/1',
136+
related: '/actors/1'
137+
}
138+
},
139+
director: {
140+
links: {
141+
self: '/movies/1',
142+
related: '/directors/1'
143+
}
144+
}
145+
}
146+
}
147+
}.to_json)
148+
stub_request(:get, 'http://example.com/directors/1')
149+
.to_return(headers: { content_type: 'application/vnd.api+json',
150+
accept: 'application/vnd.api+json' },
151+
body: {
152+
data: {
153+
id: '1',
154+
type: 'movie',
155+
attributes: {
156+
actor_id: 1,
157+
created_at: '2021-04-20T17:27:06-07:00',
158+
updated_at: '2021-04-20T17:27:07-07:00'
159+
},
160+
relationships: {
161+
actor: {
162+
links: {
163+
self: '/movies/1',
164+
related: '/actors/1'
165+
}
166+
},
167+
director: {
168+
links: {
169+
self: '/movies/1',
170+
related: '/directors/1'
171+
}
172+
}
173+
}
174+
}
175+
}.to_json)
176+
movie = Movie.find(1).last
177+
assert_equal(NUMERIC_ASSERTION, movie.id.class)
178+
assert_equal(1, movie.id)
179+
assert_equal(String, movie.attributes[:id].class)
180+
assert_equal('1', movie.attributes[:id])
181+
assert_equal(Director, movie.director.class)
182+
end
183+
end

0 commit comments

Comments
 (0)