Provide key case translation

This commit is contained in:
Ben Mills
2016-03-09 20:25:18 -07:00
parent daabb89fe0
commit c533d1a7fe
15 changed files with 979 additions and 22 deletions

View File

@@ -56,7 +56,9 @@ module ActionController
[:_render_option_json, :_render_with_renderer_json].each do |renderer_method|
define_method renderer_method do |resource, options|
options.fetch(:serialization_context) { options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request) }
options.fetch(:serialization_context) do
options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request, options)
end
serializable_resource = get_serializer(resource, options)
super(serializable_resource, options)
end

View File

@@ -26,6 +26,7 @@ module ActiveModel
# Make JSON API top-level jsonapi member opt-in
# ref: http://jsonapi.org/format/#document-top-level
config.jsonapi_include_toplevel_object = false
config.key_transform = nil
config.schema_path = 'test/support/schemas'
end

View File

@@ -1,3 +1,5 @@
require 'active_model_serializers/key_transform'
module ActiveModelSerializers
module Adapter
class Base
@@ -51,6 +53,27 @@ module ActiveModelSerializers
json[meta_key] = meta unless meta.blank?
json
end
def default_key_transform
:unaltered
end
# Determines the transform to use in order of precedence:
# serialization context, global config, adapter default.
#
# @param serialization_context [Object] the SerializationContext
# @return [Symbol] the transform to use
def key_transform(serialization_context)
serialization_context.key_transform ||
ActiveModelSerializers.config.key_transform ||
default_key_transform
end
def transform_key_casing!(value, serialization_context)
return value unless serialization_context
transform = key_transform(serialization_context)
KeyTransform.send(transform, value)
end
end
end
end

View File

@@ -3,7 +3,8 @@ module ActiveModelSerializers
class Json < Base
def serializable_hash(options = nil)
options ||= {}
{ root => Attributes.new(serializer, instance_options).serializable_hash(options) }
serialized_hash = { root => Attributes.new(serializer, instance_options).serializable_hash(options) }
transform_key_casing!(serialized_hash, options[:serialization_context])
end
end
end

View File

@@ -37,15 +37,20 @@ module ActiveModelSerializers
@fieldset = options[:fieldset] || ActiveModel::Serializer::Fieldset.new(options.delete(:fields))
end
def default_key_transform
:dashed
end
# {http://jsonapi.org/format/#crud Requests are transactional, i.e. success or failure}
# {http://jsonapi.org/format/#document-top-level data and errors MUST NOT coexist in the same document.}
def serializable_hash(options = nil)
options ||= {}
if serializer.success?
success_document(options)
else
failure_document
end
document = if serializer.success?
success_document(options)
else
failure_document
end
transform_key_casing!(document, options[:serialization_context])
end
# {http://jsonapi.org/format/#document-top-level Primary data}

View File

@@ -0,0 +1,40 @@
require 'active_support/core_ext/hash/keys'
module ActiveModelSerializers
module KeyTransform
module_function
# Transforms keys to UpperCamelCase or PascalCase.
#
# @example:
# "some_key" => "SomeKey",
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L66-L76 ActiveSupport::Inflector.camelize}
def camel(hash)
hash.deep_transform_keys! { |key| key.to_s.camelize.to_sym }
end
# Transforms keys to camelCase.
#
# @example:
# "some_key" => "someKey",
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L66-L76 ActiveSupport::Inflector.camelize}
def camel_lower(hash)
hash.deep_transform_keys! { |key| key.to_s.camelize(:lower).to_sym }
end
# Transforms keys to dashed-case.
# This is the default case for the JsonApi adapter.
#
# @example:
# "some_key" => "some-key",
# @see {https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/methods.rb#L185-L187 ActiveSupport::Inflector.dasherize}
def dashed(hash)
hash.deep_transform_keys! { |key| key.to_s.dasherize.to_sym }
end
# Returns the hash unaltered
def unaltered(hash)
hash
end
end
end

View File

@@ -4,13 +4,14 @@ module ActiveModelSerializers
attr_writer :url_helpers, :default_url_options
end
attr_reader :request_url, :query_parameters
attr_reader :request_url, :query_parameters, :key_transform
def initialize(request, options = {})
@request_url = request.original_url[/\A[^?]+/]
@query_parameters = request.query_parameters
@url_helpers = options.delete(:url_helpers) || self.class.url_helpers
@default_url_options = options.delete(:default_url_options) || self.class.default_url_options
@key_transform = options.delete(:key_transform)
end
def self.url_helpers