mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-22 22:06:50 +00:00
Support key transformation for Attributes adapter (#1889)
The `:attributes` adapter is the default one, but it did not support key transformation. This was very surprising behavior, since the "Configuration Options" page in the guides didn't mention that this behavior was not supported by the attributes adapter. This commit adds key transform support to the attributes adapter, and adds documentation about the default transform for the attributes adapter (which is `:unaltered`). This commit also handles arrays when transforming keys, which was needed in the case where you're serializing a collection with the Attributes adapter. With the JSON adapter, it was always guaranteed to pass a hash to the KeyTransform functions because of the top-level key. Since there is no top-level key for the Attributes adapter, the return value could be an array.
This commit is contained in:
parent
49ee823a53
commit
2423ca4999
@ -8,6 +8,7 @@ Features:
|
|||||||
|
|
||||||
- [#1791](https://github.com/rails-api/active_model_serializers/pull/1791) (@bf4, @youroff, @NullVoxPopuli)
|
- [#1791](https://github.com/rails-api/active_model_serializers/pull/1791) (@bf4, @youroff, @NullVoxPopuli)
|
||||||
- Added `jsonapi_namespace_separator` config option.
|
- Added `jsonapi_namespace_separator` config option.
|
||||||
|
- [#1889](https://github.com/rails-api/active_model_serializers/pull/1889) Support key transformation for Attributes adapter (@iancanderson, @danbee)
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
|
|
||||||
|
|||||||
@ -46,6 +46,7 @@ Each adapter has a default key transform configured:
|
|||||||
|
|
||||||
| Adapter | Default Key Transform |
|
| Adapter | Default Key Transform |
|
||||||
|----|----|
|
|----|----|
|
||||||
|
| `Attributes` | `:unaltered` |
|
||||||
| `Json` | `:unaltered` |
|
| `Json` | `:unaltered` |
|
||||||
| `JsonApi` | `:dash` |
|
| `JsonApi` | `:dash` |
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,9 @@ module ActiveModelSerializers
|
|||||||
def serializable_hash(options = nil)
|
def serializable_hash(options = nil)
|
||||||
options = serialization_options(options)
|
options = serialization_options(options)
|
||||||
options[:fields] ||= instance_options[:fields]
|
options[:fields] ||= instance_options[:fields]
|
||||||
serializer.serializable_hash(instance_options, options, self)
|
serialized_hash = serializer.serializable_hash(instance_options, options, self)
|
||||||
|
|
||||||
|
self.class.transform_key_casing!(serialized_hash, instance_options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -11,6 +11,7 @@ module ActiveModelSerializers
|
|||||||
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L66-L76 ActiveSupport::Inflector.camelize}
|
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L66-L76 ActiveSupport::Inflector.camelize}
|
||||||
def camel(value)
|
def camel(value)
|
||||||
case value
|
case value
|
||||||
|
when Array then value.map { |item| camel(item) }
|
||||||
when Hash then value.deep_transform_keys! { |key| camel(key) }
|
when Hash then value.deep_transform_keys! { |key| camel(key) }
|
||||||
when Symbol then camel(value.to_s).to_sym
|
when Symbol then camel(value.to_s).to_sym
|
||||||
when String then value.underscore.camelize
|
when String then value.underscore.camelize
|
||||||
@ -25,6 +26,7 @@ module ActiveModelSerializers
|
|||||||
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L66-L76 ActiveSupport::Inflector.camelize}
|
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L66-L76 ActiveSupport::Inflector.camelize}
|
||||||
def camel_lower(value)
|
def camel_lower(value)
|
||||||
case value
|
case value
|
||||||
|
when Array then value.map { |item| camel_lower(item) }
|
||||||
when Hash then value.deep_transform_keys! { |key| camel_lower(key) }
|
when Hash then value.deep_transform_keys! { |key| camel_lower(key) }
|
||||||
when Symbol then camel_lower(value.to_s).to_sym
|
when Symbol then camel_lower(value.to_s).to_sym
|
||||||
when String then value.underscore.camelize(:lower)
|
when String then value.underscore.camelize(:lower)
|
||||||
@ -40,6 +42,7 @@ module ActiveModelSerializers
|
|||||||
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L185-L187 ActiveSupport::Inflector.dasherize}
|
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L185-L187 ActiveSupport::Inflector.dasherize}
|
||||||
def dash(value)
|
def dash(value)
|
||||||
case value
|
case value
|
||||||
|
when Array then value.map { |item| dash(item) }
|
||||||
when Hash then value.deep_transform_keys! { |key| dash(key) }
|
when Hash then value.deep_transform_keys! { |key| dash(key) }
|
||||||
when Symbol then dash(value.to_s).to_sym
|
when Symbol then dash(value.to_s).to_sym
|
||||||
when String then value.underscore.dasherize
|
when String then value.underscore.dasherize
|
||||||
@ -55,6 +58,7 @@ module ActiveModelSerializers
|
|||||||
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L89-L98 ActiveSupport::Inflector.underscore}
|
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L89-L98 ActiveSupport::Inflector.underscore}
|
||||||
def underscore(value)
|
def underscore(value)
|
||||||
case value
|
case value
|
||||||
|
when Array then value.map { |item| underscore(item) }
|
||||||
when Hash then value.deep_transform_keys! { |key| underscore(key) }
|
when Hash then value.deep_transform_keys! { |key| underscore(key) }
|
||||||
when Symbol then underscore(value.to_s).to_sym
|
when Symbol then underscore(value.to_s).to_sym
|
||||||
when String then value.underscore
|
when String then value.underscore
|
||||||
|
|||||||
@ -60,6 +60,14 @@ module ActiveModelSerializers
|
|||||||
{
|
{
|
||||||
value: nil,
|
value: nil,
|
||||||
expected: nil
|
expected: nil
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: [
|
||||||
|
{ some_value: 'value' }
|
||||||
|
],
|
||||||
|
expected: [
|
||||||
|
{ SomeValue: 'value' }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
scenarios.each do |s|
|
scenarios.each do |s|
|
||||||
@ -126,6 +134,14 @@ module ActiveModelSerializers
|
|||||||
{
|
{
|
||||||
value: nil,
|
value: nil,
|
||||||
expected: nil
|
expected: nil
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: [
|
||||||
|
{ some_value: 'value' }
|
||||||
|
],
|
||||||
|
expected: [
|
||||||
|
{ someValue: 'value' }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
scenarios.each do |s|
|
scenarios.each do |s|
|
||||||
@ -188,6 +204,14 @@ module ActiveModelSerializers
|
|||||||
{
|
{
|
||||||
value: nil,
|
value: nil,
|
||||||
expected: nil
|
expected: nil
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: [
|
||||||
|
{ 'some_value' => 'value' }
|
||||||
|
],
|
||||||
|
expected: [
|
||||||
|
{ 'some-value' => 'value' }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
scenarios.each do |s|
|
scenarios.each do |s|
|
||||||
@ -254,6 +278,14 @@ module ActiveModelSerializers
|
|||||||
{
|
{
|
||||||
value: nil,
|
value: nil,
|
||||||
expected: nil
|
expected: nil
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: [
|
||||||
|
{ 'some-value' => 'value' }
|
||||||
|
],
|
||||||
|
expected: [
|
||||||
|
{ 'some_value' => 'value' }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
scenarios.each do |s|
|
scenarios.each do |s|
|
||||||
|
|||||||
43
test/adapter/attributes_test.rb
Normal file
43
test/adapter/attributes_test.rb
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
module ActiveModelSerializers
|
||||||
|
module Adapter
|
||||||
|
class AttributesTest < ActiveSupport::TestCase
|
||||||
|
class Person
|
||||||
|
include ActiveModel::Model
|
||||||
|
include ActiveModel::Serialization
|
||||||
|
|
||||||
|
attr_accessor :first_name, :last_name
|
||||||
|
end
|
||||||
|
|
||||||
|
class PersonSerializer < ActiveModel::Serializer
|
||||||
|
attributes :first_name, :last_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup
|
||||||
|
ActionController::Base.cache_store.clear
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_serializable_hash
|
||||||
|
person = Person.new(first_name: 'Arthur', last_name: 'Dent')
|
||||||
|
serializer = PersonSerializer.new(person)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::Attributes.new(serializer)
|
||||||
|
|
||||||
|
assert_equal({ first_name: 'Arthur', last_name: 'Dent' },
|
||||||
|
adapter.serializable_hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_serializable_hash_with_transform_key_casing
|
||||||
|
person = Person.new(first_name: 'Arthur', last_name: 'Dent')
|
||||||
|
serializer = PersonSerializer.new(person)
|
||||||
|
adapter = ActiveModelSerializers::Adapter::Attributes.new(
|
||||||
|
serializer,
|
||||||
|
key_transform: :camel_lower
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_equal({ firstName: 'Arthur', lastName: 'Dent' },
|
||||||
|
adapter.serializable_hash)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in New Issue
Block a user