Skip to content

Commit b73b780

Browse files
committed
Merge pull request #1629 from lawitschka/key-transform-on-deserialization
Properly deserialize dasherized keys
2 parents a355b26 + afe786d commit b73b780

File tree

3 files changed

+37
-8
lines changed

3 files changed

+37
-8
lines changed

lib/active_model_serializers/adapter/json_api/deserialization.rb

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ def field_key(field, options)
155155

156156
# @api private
157157
def parse_attributes(attributes, options)
158-
attributes
158+
transform_keys(attributes, options)
159159
.map { |(k, v)| { field_key(k, options) => v } }
160160
.reduce({}, :merge)
161161
end
@@ -182,23 +182,29 @@ def parse_relationship(assoc_name, assoc_data, options)
182182
prefix_key = field_key(assoc_name, options).to_s.singularize
183183
hash =
184184
if assoc_data.is_a?(Array)
185-
{ "#{prefix_key}_ids".to_sym => assoc_data.map { |ri| ri['id'] } }
185+
{ "#{prefix_key}_ids".to_sym => assoc_data.map { |ri| ri[:id] } }
186186
else
187-
{ "#{prefix_key}_id".to_sym => assoc_data ? assoc_data['id'] : nil }
187+
{ "#{prefix_key}_id".to_sym => assoc_data && assoc_data.is_a?(Hash) ? assoc_data[:id] : nil }
188188
end
189189

190190
polymorphic = (options[:polymorphic] || []).include?(assoc_name.to_sym)
191-
hash["#{prefix_key}_type".to_sym] = assoc_data['type'] if polymorphic
191+
hash["#{prefix_key}_type".to_sym] = assoc_data[:type] if polymorphic
192192

193193
hash
194194
end
195195

196196
# @api private
197197
def parse_relationships(relationships, options)
198-
relationships
199-
.map { |(k, v)| parse_relationship(k, v['data'], options) }
198+
transform_keys(relationships, options)
199+
.map { |(k, v)| parse_relationship(k, v[:data], options) }
200200
.reduce({}, :merge)
201201
end
202+
203+
# @api private
204+
def transform_keys(hash, options)
205+
transform = options[:key_transform] || :underscore
206+
KeyTransform.send(transform, hash)
207+
end
202208
end
203209
end
204210
end

lib/active_model_serializers/key_transform.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ def dashed(hash)
3232
hash.deep_transform_keys! { |key| key.to_s.dasherize.to_sym }
3333
end
3434

35+
# Transforms keys to underscore.
36+
# This is the default case for deserialization in the JsonApi adapter.
37+
#
38+
# @example:
39+
# "some-key" => "some_key",
40+
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L89-L98 ActiveSupport::Inflector.underscore}
41+
def underscore(hash)
42+
hash.deep_transform_keys! { |key| key.to_s.underscore.to_sym }
43+
end
44+
3545
# Returns the hash unaltered
3646
def unaltered(hash)
3747
hash

test/action_controller/json_api/deserialization_test.rb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ def test_deserialization
2020
'id' => 'zorglub',
2121
'attributes' => {
2222
'title' => 'Ember Hamster',
23-
'src' => 'http://example.com/images/productivity.png'
23+
'src' => 'http://example.com/images/productivity.png',
24+
'image-width' => '200',
25+
'imageHeight' => '200',
26+
'ImageSize' => '1024'
2427
},
2528
'relationships' => {
2629
'author' => {
@@ -34,6 +37,12 @@ def test_deserialization
3437
{ 'type' => 'comments', 'id' => '1' },
3538
{ 'type' => 'comments', 'id' => '2' }
3639
]
40+
},
41+
'related-images' => {
42+
'data' => [
43+
{ 'type' => 'image', 'id' => '7' },
44+
{ 'type' => 'image', 'id' => '8' }
45+
]
3746
}
3847
}
3948
}
@@ -46,9 +55,13 @@ def test_deserialization
4655
'id' => 'zorglub',
4756
'title' => 'Ember Hamster',
4857
'src' => 'http://example.com/images/productivity.png',
58+
'image_width' => '200',
59+
'image_height' => '200',
60+
'image_size' => '1024',
4961
'author_id' => nil,
5062
'photographer_id' => '9',
51-
'comment_ids' => %w(1 2)
63+
'comment_ids' => %w(1 2),
64+
'related_image_ids' => %w(7 8)
5265
}
5366

5467
assert_equal(expected, response)

0 commit comments

Comments
 (0)