mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-23 06:16:50 +00:00
Properly deserialize dasherized keys
The JSON API adapater dasherizes every key, but the deserializer left the keys unaltered. Thus, the client had to send underscored keys in the request body in order for Rails to properly match sent values to model attributes. This commit adds automatic key transformation on deserialization. Per default the deserializer transforms the keys to underscore, but this behaviour can also be changed by including `key_transform` in the deserializer options.
This commit is contained in:
parent
c7b2916f37
commit
afe786d19a
@ -155,7 +155,7 @@ module ActiveModelSerializers
|
||||
|
||||
# @api private
|
||||
def parse_attributes(attributes, options)
|
||||
attributes
|
||||
transform_keys(attributes, options)
|
||||
.map { |(k, v)| { field_key(k, options) => v } }
|
||||
.reduce({}, :merge)
|
||||
end
|
||||
@ -182,23 +182,29 @@ module ActiveModelSerializers
|
||||
prefix_key = field_key(assoc_name, options).to_s.singularize
|
||||
hash =
|
||||
if assoc_data.is_a?(Array)
|
||||
{ "#{prefix_key}_ids".to_sym => assoc_data.map { |ri| ri['id'] } }
|
||||
{ "#{prefix_key}_ids".to_sym => assoc_data.map { |ri| ri[:id] } }
|
||||
else
|
||||
{ "#{prefix_key}_id".to_sym => assoc_data ? assoc_data['id'] : nil }
|
||||
{ "#{prefix_key}_id".to_sym => assoc_data && assoc_data.is_a?(Hash) ? assoc_data[:id] : nil }
|
||||
end
|
||||
|
||||
polymorphic = (options[:polymorphic] || []).include?(assoc_name.to_sym)
|
||||
hash["#{prefix_key}_type".to_sym] = assoc_data['type'] if polymorphic
|
||||
hash["#{prefix_key}_type".to_sym] = assoc_data[:type] if polymorphic
|
||||
|
||||
hash
|
||||
end
|
||||
|
||||
# @api private
|
||||
def parse_relationships(relationships, options)
|
||||
relationships
|
||||
.map { |(k, v)| parse_relationship(k, v['data'], options) }
|
||||
transform_keys(relationships, options)
|
||||
.map { |(k, v)| parse_relationship(k, v[:data], options) }
|
||||
.reduce({}, :merge)
|
||||
end
|
||||
|
||||
# @api private
|
||||
def transform_keys(hash, options)
|
||||
transform = options[:key_transform] || :underscore
|
||||
KeyTransform.send(transform, hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -32,6 +32,16 @@ module ActiveModelSerializers
|
||||
hash.deep_transform_keys! { |key| key.to_s.dasherize.to_sym }
|
||||
end
|
||||
|
||||
# Transforms keys to underscore.
|
||||
# This is the default case for deserialization in the JsonApi adapter.
|
||||
#
|
||||
# @example:
|
||||
# "some-key" => "some_key",
|
||||
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L89-L98 ActiveSupport::Inflector.underscore}
|
||||
def underscore(hash)
|
||||
hash.deep_transform_keys! { |key| key.to_s.underscore.to_sym }
|
||||
end
|
||||
|
||||
# Returns the hash unaltered
|
||||
def unaltered(hash)
|
||||
hash
|
||||
|
||||
@ -20,7 +20,10 @@ module ActionController
|
||||
'id' => 'zorglub',
|
||||
'attributes' => {
|
||||
'title' => 'Ember Hamster',
|
||||
'src' => 'http://example.com/images/productivity.png'
|
||||
'src' => 'http://example.com/images/productivity.png',
|
||||
'image-width' => '200',
|
||||
'imageHeight' => '200',
|
||||
'ImageSize' => '1024'
|
||||
},
|
||||
'relationships' => {
|
||||
'author' => {
|
||||
@ -34,6 +37,12 @@ module ActionController
|
||||
{ 'type' => 'comments', 'id' => '1' },
|
||||
{ 'type' => 'comments', 'id' => '2' }
|
||||
]
|
||||
},
|
||||
'related-images' => {
|
||||
'data' => [
|
||||
{ 'type' => 'image', 'id' => '7' },
|
||||
{ 'type' => 'image', 'id' => '8' }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -46,9 +55,13 @@ module ActionController
|
||||
'id' => 'zorglub',
|
||||
'title' => 'Ember Hamster',
|
||||
'src' => 'http://example.com/images/productivity.png',
|
||||
'image_width' => '200',
|
||||
'image_height' => '200',
|
||||
'image_size' => '1024',
|
||||
'author_id' => nil,
|
||||
'photographer_id' => '9',
|
||||
'comment_ids' => %w(1 2)
|
||||
'comment_ids' => %w(1 2),
|
||||
'related_image_ids' => %w(7 8)
|
||||
}
|
||||
|
||||
assert_equal(expected, response)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user