Skip to content

Commit 9745a2f

Browse files
committed
Fix: ResourceIdentifier.for_type_with_id can serialize unpersisted resources
1 parent 5916014 commit 9745a2f

File tree

2 files changed

+54
-29
lines changed

2 files changed

+54
-29
lines changed

lib/active_model_serializers/adapter/json_api/resource_identifier.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ def self.type_for(serializer, serializer_type = nil, transform_options = {})
88
end
99

1010
def self.for_type_with_id(type, id, options)
11-
return nil if id.blank?
1211
type = inflect_type(type)
13-
{
14-
id: id.to_s,
15-
type: type_for(:no_class_needed, type, options)
16-
}
12+
type = type_for(:no_class_needed, type, options)
13+
if id.blank?
14+
{ type: type }
15+
else
16+
{ id: id.to_s, type: type }
17+
end
1718
end
1819

1920
def self.raw_type_from_serializer_object(object)

test/adapter/json_api/type_test.rb

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -72,33 +72,33 @@ def id
7272

7373
def test_defined_type
7474
actual = with_jsonapi_inflection :plural do
75-
actual_resource_identifier_object(WithDefinedTypeSerializer)
75+
actual_resource_identifier_object(WithDefinedTypeSerializer, @model)
7676
end
77-
expected = { id: expected_model_id, type: 'with-defined-types' }
77+
expected = { id: expected_model_id(@model), type: 'with-defined-types' }
7878
assert_equal actual, expected
7979
end
8080

8181
def test_defined_type_not_inflected
8282
actual = with_jsonapi_inflection :singular do
83-
actual_resource_identifier_object(WithDefinedTypeSerializer)
83+
actual_resource_identifier_object(WithDefinedTypeSerializer, @model)
8484
end
85-
expected = { id: expected_model_id, type: 'with-defined-types' }
85+
expected = { id: expected_model_id(@model), type: 'with-defined-types' }
8686
assert_equal actual, expected
8787
end
8888

8989
def test_singular_type
9090
actual = with_jsonapi_inflection :singular do
91-
actual_resource_identifier_object(AuthorSerializer)
91+
actual_resource_identifier_object(AuthorSerializer, @model)
9292
end
93-
expected = { id: expected_model_id, type: 'author' }
93+
expected = { id: expected_model_id(@model), type: 'author' }
9494
assert_equal actual, expected
9595
end
9696

9797
def test_plural_type
9898
actual = with_jsonapi_inflection :plural do
99-
actual_resource_identifier_object(AuthorSerializer)
99+
actual_resource_identifier_object(AuthorSerializer, @model)
100100
end
101-
expected = { id: expected_model_id, type: 'authors' }
101+
expected = { id: expected_model_id(@model), type: 'authors' }
102102
assert_equal actual, expected
103103
end
104104

@@ -123,45 +123,69 @@ def test_type_with_namespace
123123
end
124124

125125
def test_id_defined_on_object
126-
actual = actual_resource_identifier_object(AuthorSerializer)
127-
expected = { id: @model.id.to_s, type: expected_model_type }
126+
actual = actual_resource_identifier_object(AuthorSerializer, @model)
127+
expected = { id: @model.id.to_s, type: expected_model_type(@model) }
128128
assert_equal actual, expected
129129
end
130130

131131
def test_blank_id
132-
@model.id = nil
133-
actual = actual_resource_identifier_object(AuthorSerializer)
134-
expected = { type: expected_model_type }
132+
model = Author.new(id: nil, name: 'Steve K.')
133+
actual = actual_resource_identifier_object(AuthorSerializer, model)
134+
expected = { type: expected_model_type(model) }
135+
assert_equal actual, expected
136+
end
137+
138+
def test_for_type_with_id
139+
id = 1
140+
actual = ResourceIdentifier.for_type_with_id('admin_user', id, {})
141+
expected = { id: "1", type: 'admin-users' }
142+
assert_equal actual, expected
143+
end
144+
145+
def test_for_type_with_id_given_blank_id
146+
id = ""
147+
actual = ResourceIdentifier.for_type_with_id('admin_user', id, {})
148+
expected = { type: 'admin-users' }
149+
assert_equal actual, expected
150+
end
151+
152+
def test_for_type_with_id_inflected
153+
id = 2
154+
actual = with_jsonapi_inflection :singular do
155+
ResourceIdentifier.for_type_with_id('admin_users', id, {})
156+
end
157+
expected = { id: "2", type: 'admin-user' }
135158
assert_equal actual, expected
136159
end
137160

138161
def test_id_defined_on_serializer
139-
actual = actual_resource_identifier_object(WithDefinedIdSerializer)
140-
expected = { id: 'special_id', type: expected_model_type }
162+
actual = actual_resource_identifier_object(WithDefinedIdSerializer, @model)
163+
expected = { id: 'special_id', type: expected_model_type(@model) }
141164
assert_equal actual, expected
142165
end
143166

144167
def test_id_defined_on_fragmented
145-
actual = actual_resource_identifier_object(FragmentedSerializer)
146-
expected = { id: 'special_id', type: expected_model_type }
168+
actual = actual_resource_identifier_object(FragmentedSerializer, @model)
169+
expected = { id: 'special_id', type: expected_model_type(@model) }
147170
assert_equal actual, expected
148171
end
149172

150173
private
151174

152-
def actual_resource_identifier_object(serializer_class)
153-
serializer = serializer_class.new(@model)
175+
def actual_resource_identifier_object(serializer_class, model)
176+
serializer = serializer_class.new(model)
154177
resource_identifier = ResourceIdentifier.new(serializer, nil)
155178
resource_identifier.as_json
156179
end
157180

158-
def expected_model_type
159-
inflection = ActiveModelSerializers.config.jsonapi_resource_type
160-
@model.class.model_name.send(inflection)
181+
def expected_model_type(model, inflection = ActiveModelSerializers.config.jsonapi_resource_type)
182+
with_jsonapi_inflection inflection do
183+
model.class.model_name.send(inflection)
184+
end
161185
end
162186

163-
def expected_model_id
164-
@model.id.to_s
187+
def expected_model_id(model)
188+
model.id.to_s
165189
end
166190
end
167191
end

0 commit comments

Comments
 (0)