Apply key transforms to keys referenced in values

This commit is contained in:
Ben Mills
2016-03-31 14:24:31 -06:00
parent d30aa4c44f
commit 3498647d1a
30 changed files with 579 additions and 223 deletions

View File

@@ -10,7 +10,7 @@ module ActionController
type 'posts'
attributes :title, :body, :publish_at
belongs_to :author
has_many :comments
has_many :top_comments
link(:post_authors) { 'https://example.com/post_authors' }
@@ -28,9 +28,9 @@ module ActionController
attributes :first_name, :last_name
end
Comment = Class.new(::Model)
class CommentSerializer < ActiveModel::Serializer
type 'comments'
TopComment = Class.new(::Model)
class TopCommentSerializer < ActiveModel::Serializer
type 'top_comments'
attributes :body
belongs_to :author
end
@@ -38,28 +38,28 @@ module ActionController
def setup_post
ActionController::Base.cache_store.clear
@author = Author.new(id: 1, first_name: 'Bob', last_name: 'Jones')
@comment1 = Comment.new(id: 7, body: 'cool', author: @author)
@comment2 = Comment.new(id: 12, body: 'awesome', author: @author)
@comment1 = TopComment.new(id: 7, body: 'cool', author: @author)
@comment2 = TopComment.new(id: 12, body: 'awesome', author: @author)
@post = Post.new(id: 1337, title: 'Title 1', body: 'Body 1',
author: @author, comments: [@comment1, @comment2],
author: @author, top_comments: [@comment1, @comment2],
publish_at: '2020-03-16T03:55:25.291Z')
@comment1.post = @post
@comment2.post = @post
end
def render_resource_with_key_transform
def render_resource_with_transform
setup_post
render json: @post, serializer: PostSerializer, adapter: :json_api,
key_transform: :camel
end
def render_resource_with_key_transform_nil
def render_resource_with_transform_nil
setup_post
render json: @post, serializer: PostSerializer, adapter: :json_api,
key_transform: nil
end
def render_resource_with_key_transform_with_global_config
def render_resource_with_transform_with_global_config
setup_post
old_transform = ActiveModelSerializers.config.key_transform
ActiveModelSerializers.config.key_transform = :camel_lower
@@ -70,13 +70,13 @@ module ActionController
tests KeyTransformTestController
def test_render_resource_with_key_transform
get :render_resource_with_key_transform
def test_render_resource_with_transform
get :render_resource_with_transform
response = JSON.parse(@response.body)
expected = {
'Data' => {
'Id' => '1337',
'Type' => 'posts',
'Type' => 'Posts',
'Attributes' => {
'Title' => 'Title 1',
'Body' => 'Body 1',
@@ -86,13 +86,13 @@ module ActionController
'Author' => {
'Data' => {
'Id' => '1',
'Type' => 'authors'
'Type' => 'Authors'
}
},
'Comments' => {
'TopComments' => {
'Data' => [
{ 'Id' => '7', 'Type' => 'comments' },
{ 'Id' => '12', 'Type' => 'comments' }
{ 'Id' => '7', 'Type' => 'TopComments' },
{ 'Id' => '12', 'Type' => 'TopComments' }
]
}
},
@@ -105,8 +105,8 @@ module ActionController
assert_equal expected, response
end
def test_render_resource_with_key_transform_nil
get :render_resource_with_key_transform_nil
def test_render_resource_with_transform_nil
get :render_resource_with_transform_nil
response = JSON.parse(@response.body)
expected = {
'data' => {
@@ -124,10 +124,10 @@ module ActionController
'type' => 'authors'
}
},
'comments' => {
'top-comments' => {
'data' => [
{ 'id' => '7', 'type' => 'comments' },
{ 'id' => '12', 'type' => 'comments' }
{ 'id' => '7', 'type' => 'top-comments' },
{ 'id' => '12', 'type' => 'top-comments' }
]
}
},
@@ -140,8 +140,8 @@ module ActionController
assert_equal expected, response
end
def test_render_resource_with_key_transform_with_global_config
get :render_resource_with_key_transform_with_global_config
def test_render_resource_with_transform_with_global_config
get :render_resource_with_transform_with_global_config
response = JSON.parse(@response.body)
expected = {
'data' => {
@@ -159,10 +159,10 @@ module ActionController
'type' => 'authors'
}
},
'comments' => {
'topComments' => {
'data' => [
{ 'id' => '7', 'type' => 'comments' },
{ 'id' => '12', 'type' => 'comments' }
{ 'id' => '7', 'type' => 'topComments' },
{ 'id' => '12', 'type' => 'topComments' }
]
}
},

View File

@@ -0,0 +1,263 @@
require 'test_helper'
class ActiveModelSerializers::KeyTransformTest < ActiveSupport::TestCase
def test_camel
obj = Object.new
scenarios = [
{
value: { :"some-key" => 'value' },
expected: { :SomeKey => 'value' }
},
{
value: { :someKey => 'value' },
expected: { :SomeKey => 'value' }
},
{
value: { :some_key => 'value' },
expected: { :SomeKey => 'value' }
},
{
value: { 'some-key' => 'value' },
expected: { 'SomeKey' => 'value' }
},
{
value: { 'someKey' => 'value' },
expected: { 'SomeKey' => 'value' }
},
{
value: { 'some_key' => 'value' },
expected: { 'SomeKey' => 'value' }
},
{
value: :"some-value",
expected: :SomeValue
},
{
value: :some_value,
expected: :SomeValue
},
{
value: :someValue,
expected: :SomeValue
},
{
value: 'some-value',
expected: 'SomeValue'
},
{
value: 'someValue',
expected: 'SomeValue'
},
{
value: 'some_value',
expected: 'SomeValue'
},
{
value: obj,
expected: obj
},
{
value: nil,
expected: nil
}
]
scenarios.each do |s|
result = ActiveModelSerializers::KeyTransform.camel(s[:value])
assert_equal s[:expected], result
end
end
def test_camel_lower
obj = Object.new
scenarios = [
{
value: { :"some-key" => 'value' },
expected: { :someKey => 'value' }
},
{
value: { :SomeKey => 'value' },
expected: { :someKey => 'value' }
},
{
value: { :some_key => 'value' },
expected: { :someKey => 'value' }
},
{
value: { 'some-key' => 'value' },
expected: { 'someKey' => 'value' }
},
{
value: { 'SomeKey' => 'value' },
expected: { 'someKey' => 'value' }
},
{
value: { 'some_key' => 'value' },
expected: { 'someKey' => 'value' }
},
{
value: :"some-value",
expected: :someValue
},
{
value: :SomeValue,
expected: :someValue
},
{
value: :some_value,
expected: :someValue
},
{
value: 'some-value',
expected: 'someValue'
},
{
value: 'SomeValue',
expected: 'someValue'
},
{
value: 'some_value',
expected: 'someValue'
},
{
value: obj,
expected: obj
},
{
value: nil,
expected: nil
}
]
scenarios.each do |s|
result = ActiveModelSerializers::KeyTransform.camel_lower(s[:value])
assert_equal s[:expected], result
end
end
def test_dash
obj = Object.new
scenarios = [
{
value: { :some_key => 'value' },
expected: { :"some-key" => 'value' }
},
{
value: { 'some_key' => 'value' },
expected: { 'some-key' => 'value' }
},
{
value: { :SomeKey => 'value' },
expected: { :"some-key" => 'value' }
},
{
value: { 'SomeKey' => 'value' },
expected: { 'some-key' => 'value' }
},
{
value: { :someKey => 'value' },
expected: { :"some-key" => 'value' }
},
{
value: { 'someKey' => 'value' },
expected: { 'some-key' => 'value' }
},
{
value: :some_value,
expected: :"some-value"
},
{
value: :SomeValue,
expected: :"some-value"
},
{
value: 'SomeValue',
expected: 'some-value'
},
{
value: :someValue,
expected: :"some-value"
},
{
value: 'someValue',
expected: 'some-value'
},
{
value: obj,
expected: obj
},
{
value: nil,
expected: nil
}
]
scenarios.each do |s|
result = ActiveModelSerializers::KeyTransform.dash(s[:value])
assert_equal s[:expected], result
end
end
def test_underscore
obj = Object.new
scenarios = [
{
value: { :"some-key" => 'value' },
expected: { :some_key => 'value' }
},
{
value: { 'some-key' => 'value' },
expected: { 'some_key' => 'value' }
},
{
value: { :SomeKey => 'value' },
expected: { :some_key => 'value' }
},
{
value: { 'SomeKey' => 'value' },
expected: { 'some_key' => 'value' }
},
{
value: { :someKey => 'value' },
expected: { :some_key => 'value' }
},
{
value: { 'someKey' => 'value' },
expected: { 'some_key' => 'value' }
},
{
value: :"some-value",
expected: :some_value
},
{
value: :SomeValue,
expected: :some_value
},
{
value: :someValue,
expected: :some_value
},
{
value: 'some-value',
expected: 'some_value'
},
{
value: 'SomeValue',
expected: 'some_value'
},
{
value: 'someValue',
expected: 'some_value'
},
{
value: obj,
expected: obj
},
{
value: nil,
expected: nil
}
]
scenarios.each do |s|
result = ActiveModelSerializers::KeyTransform.underscore(s[:value])
assert_equal s[:expected], result
end
end
end

View File

@@ -8,8 +8,8 @@ module ActiveModelSerializers
context = Minitest::Mock.new
context.expect(:request_url, URI)
context.expect(:query_parameters, {})
context.expect(:key_transform, key_transform)
@options = {}
@options[:key_transform] = key_transform if key_transform
@options[:serialization_context] = context
end
@@ -25,14 +25,14 @@ module ActiveModelSerializers
@adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
end
def test_key_transform_default
def test_transform_default
mock_request
assert_equal({
blog: { id: 1, special_attribute: 'neat', articles: nil }
}, @adapter.serializable_hash(@options))
end
def test_key_transform_global_config
def test_transform_global_config
mock_request
result = with_config(key_transform: :camel_lower) do
@adapter.serializable_hash(@options)
@@ -42,7 +42,7 @@ module ActiveModelSerializers
}, result)
end
def test_key_transform_serialization_ctx_overrides_global_config
def test_transform_serialization_ctx_overrides_global_config
mock_request(:camel)
result = with_config(key_transform: :camel_lower) do
@adapter.serializable_hash(@options)
@@ -52,7 +52,7 @@ module ActiveModelSerializers
}, result)
end
def test_key_transform_undefined
def test_transform_undefined
mock_request(:blam)
result = nil
assert_raises NoMethodError do
@@ -60,28 +60,28 @@ module ActiveModelSerializers
end
end
def test_key_transform_dashed
mock_request(:dashed)
def test_transform_dash
mock_request(:dash)
assert_equal({
blog: { id: 1, :"special-attribute" => 'neat', articles: nil }
}, @adapter.serializable_hash(@options))
end
def test_key_transform_unaltered
def test_transform_unaltered
mock_request(:unaltered)
assert_equal({
blog: { id: 1, special_attribute: 'neat', articles: nil }
}, @adapter.serializable_hash(@options))
end
def test_key_transform_camel
def test_transform_camel
mock_request(:camel)
assert_equal({
Blog: { Id: 1, SpecialAttribute: 'neat', Articles: nil }
}, @adapter.serializable_hash(@options))
end
def test_key_transform_camel_lower
def test_transform_camel_lower
mock_request(:camel_lower)
assert_equal({
blog: { id: 1, specialAttribute: 'neat', articles: nil }

View File

@@ -129,7 +129,7 @@ module ActiveModelSerializers
assert_equal({
data: {
id: '1',
type: 'virtual_values',
type: 'virtual-values',
relationships: {
maker: { data: { id: 1 } },
reviews: { data: [{ id: 1 }, { id: 2 }] }

View File

@@ -63,7 +63,7 @@ module ActiveModelSerializers
expected = {
data: {
id: '1',
type: 'virtual_values',
type: 'virtual-values',
relationships: {
maker: { data: { id: 1 } },
reviews: { data: [{ id: 1 }, { id: 2 }] }

View File

@@ -216,7 +216,7 @@ module ActiveModelSerializers
expected = {
related: {
data: [{
type: 'spam_unrelated_links',
type: 'spam-unrelated-links',
id: '456'
}]
}
@@ -366,12 +366,12 @@ module ActiveModelSerializers
adapter: :json_api,
include: '*').serializable_hash
expected = [
type: 'nested_posts', id: '2',
type: 'nested-posts', id: '2',
relationships: {
nested_posts: {
:"nested-posts" => {
data: [
{ type: 'nested_posts', id: '1' },
{ type: 'nested_posts', id: '2' }
{ type: 'nested-posts', id: '1' },
{ type: 'nested-posts', id: '2' }
]
}
}

View File

@@ -80,10 +80,10 @@ module ActiveModelSerializers
}
},
author: 'http://example.com/link_authors/1337',
link_authors: 'http://example.com/link_authors',
:"link-authors" => 'http://example.com/link_authors',
resource: 'http://example.com/resource',
posts: 'http://example.com/link_authors/1337/posts',
yet_another: 'http://example.com/resource/1337'
:"yet-another" => 'http://example.com/resource/1337'
}
assert_equal(expected, hash[:data][:links])
end

View File

@@ -25,7 +25,6 @@ module ActiveModelSerializers
context = Minitest::Mock.new
context.expect(:request_url, original_url)
context.expect(:query_parameters, query_parameters)
context.expect(:key_transform, nil)
@options = {}
@options[:serialization_context] = context
end

View File

@@ -151,11 +151,8 @@ module ActiveModelSerializers
private
def test_relationship(expected, params = {})
options = params.fetch(:options, {})
links = params.fetch(:links, {})
meta = params[:meta]
parent_serializer = AuthorSerializer.new(@author)
relationship = Relationship.new(parent_serializer, @serializer, options, links, meta)
relationship = Relationship.new(parent_serializer, @serializer, nil, params)
assert_equal(expected, relationship.as_json)
end
end

View File

@@ -22,7 +22,7 @@ module ActiveModelSerializers
end
def test_defined_type
test_type(WithDefinedTypeSerializer, 'with_defined_type')
test_type(WithDefinedTypeSerializer, 'with-defined-type')
end
def test_singular_type
@@ -58,7 +58,7 @@ module ActiveModelSerializers
def test_type(serializer_class, expected_type)
serializer = serializer_class.new(@model)
resource_identifier = ResourceIdentifier.new(serializer)
resource_identifier = ResourceIdentifier.new(serializer, nil)
expected = {
id: @model.id.to_s,
type: expected_type
@@ -69,7 +69,7 @@ module ActiveModelSerializers
def test_id(serializer_class, id)
serializer = serializer_class.new(@model)
resource_identifier = ResourceIdentifier.new(serializer)
resource_identifier = ResourceIdentifier.new(serializer, nil)
inflection = ActiveModelSerializers.config.jsonapi_resource_type
type = @model.class.model_name.send(inflection)
expected = {

View File

@@ -54,7 +54,7 @@ module ActiveModel
adapter: :json_api
).serializable_hash
expected = {
comments_count: @post.comments.count
:"comments-count" => @post.comments.count
}
assert_equal(expected, hash[:data][:meta])
end
@@ -69,8 +69,8 @@ module ActiveModel
).serializable_hash
expected = {
:data => [
{ :id => '1337', :type => 'posts', :meta => { :comments_count => 0 } },
{ :id => '1339', :type => 'posts', :meta => { :comments_count => 1 } }
{ :id => '1337', :type => 'posts', :meta => { :"comments-count" => 0 } },
{ :id => '1339', :type => 'posts', :meta => { :"comments-count" => 1 } }
]
}
assert_equal(expected, hash)

View File

@@ -36,13 +36,13 @@ module ActiveModelSerializers
belongs_to :author
end
def mock_request(key_transform = nil)
def mock_request(transform = nil)
context = Minitest::Mock.new
context.expect(:request_url, URI)
context.expect(:query_parameters, {})
context.expect(:key_transform, key_transform)
context.expect(:url_helpers, Rails.application.routes.url_helpers)
@options = {}
@options[:key_transform] = transform if transform
@options[:serialization_context] = context
end
@@ -64,7 +64,7 @@ module ActiveModelSerializers
@comment2.post = @post
end
def test_success_document_key_transform_default
def test_success_document_transform_default
mock_request
serializer = PostSerializer.new(@post)
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
@@ -98,7 +98,7 @@ module ActiveModelSerializers
}, result)
end
def test_success_document_key_transform_global_config
def test_success_document_transform_global_config
mock_request
result = with_config(key_transform: :camel_lower) do
serializer = PostSerializer.new(@post)
@@ -134,7 +134,7 @@ module ActiveModelSerializers
}, result)
end
def test_success_doc_key_transform_serialization_ctx_overrides_global
def test_success_doc_transform_serialization_ctx_overrides_global
mock_request(:camel)
result = with_config(key_transform: :camel_lower) do
serializer = PostSerializer.new(@post)
@@ -144,7 +144,7 @@ module ActiveModelSerializers
assert_equal({
Data: {
Id: '1337',
Type: 'posts',
Type: 'Posts',
Attributes: {
Title: 'Title 1',
Body: 'Body 1',
@@ -152,12 +152,12 @@ module ActiveModelSerializers
},
Relationships: {
Author: {
Data: { Id: '1', Type: 'authors' }
Data: { Id: '1', Type: 'Authors' }
},
Comments: {
Data: [
{ Id: '7', Type: 'comments' },
{ Id: '12', Type: 'comments' }
{ Id: '7', Type: 'Comments' },
{ Id: '12', Type: 'Comments' }
] }
},
Links: {
@@ -170,8 +170,8 @@ module ActiveModelSerializers
}, result)
end
def test_success_document_key_transform_dashed
mock_request(:dashed)
def test_success_document_transform_dash
mock_request(:dash)
serializer = PostSerializer.new(@post)
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
result = adapter.serializable_hash(@options)
@@ -204,7 +204,7 @@ module ActiveModelSerializers
}, result)
end
def test_success_document_key_transform_unaltered
def test_success_document_transform_unaltered
mock_request(:unaltered)
serializer = PostSerializer.new(@post)
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
@@ -238,7 +238,7 @@ module ActiveModelSerializers
}, result)
end
def test_success_document_key_transform_undefined
def test_success_document_transform_undefined
mock_request(:zoot)
serializer = PostSerializer.new(@post)
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
@@ -247,7 +247,7 @@ module ActiveModelSerializers
end
end
def test_success_document_key_transform_camel
def test_success_document_transform_camel
mock_request(:camel)
serializer = PostSerializer.new(@post)
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
@@ -255,7 +255,7 @@ module ActiveModelSerializers
assert_equal({
Data: {
Id: '1337',
Type: 'posts',
Type: 'Posts',
Attributes: {
Title: 'Title 1',
Body: 'Body 1',
@@ -263,12 +263,12 @@ module ActiveModelSerializers
},
Relationships: {
Author: {
Data: { Id: '1', Type: 'authors' }
Data: { Id: '1', Type: 'Authors' }
},
Comments: {
Data: [
{ Id: '7', Type: 'comments' },
{ Id: '12', Type: 'comments' }
{ Id: '7', Type: 'Comments' },
{ Id: '12', Type: 'Comments' }
] }
},
Links: {
@@ -281,7 +281,7 @@ module ActiveModelSerializers
}, result)
end
def test_success_document_key_transform_camel_lower
def test_success_document_transform_camel_lower
mock_request(:camel_lower)
serializer = PostSerializer.new(@post)
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
@@ -315,7 +315,7 @@ module ActiveModelSerializers
}, result)
end
def test_error_document_key_transform_default
def test_error_document_transform_default
mock_request
resource = ModelWithErrors.new
resource.errors.add(:published_at, 'must be in the future')
@@ -327,7 +327,7 @@ module ActiveModelSerializers
{ :errors =>
[
{
:source => { :pointer => '/data/attributes/published_at' },
:source => { :pointer => '/data/attributes/published-at' },
:detail => 'must be in the future' },
{
:source => { :pointer => '/data/attributes/title' },
@@ -338,7 +338,7 @@ module ActiveModelSerializers
assert_equal expected_errors_object, result
end
def test_error_document_key_transform_global_config
def test_error_document_transform_global_config
mock_request
result = with_config(key_transform: :camel) do
resource = ModelWithErrors.new
@@ -352,11 +352,11 @@ module ActiveModelSerializers
{ :Errors =>
[
{
:Source => { :Pointer => '/data/attributes/published_at' },
:Source => { :Pointer => '/data/attributes/PublishedAt' },
:Detail => 'must be in the future'
},
{
:Source => { :Pointer => '/data/attributes/title' },
:Source => { :Pointer => '/data/attributes/Title' },
:Detail => 'must be longer'
}
]
@@ -364,7 +364,7 @@ module ActiveModelSerializers
assert_equal expected_errors_object, result
end
def test_error_document_key_transform_serialization_ctx_overrides_global
def test_error_document_transform_serialization_ctx_overrides_global
mock_request(:camel)
result = with_config(key_transform: :camel_lower) do
resource = ModelWithErrors.new
@@ -378,11 +378,11 @@ module ActiveModelSerializers
{ :Errors =>
[
{
:Source => { :Pointer => '/data/attributes/published_at' },
:Source => { :Pointer => '/data/attributes/PublishedAt' },
:Detail => 'must be in the future'
},
{
:Source => { :Pointer => '/data/attributes/title' },
:Source => { :Pointer => '/data/attributes/Title' },
:Detail => 'must be longer'
}
]
@@ -390,8 +390,8 @@ module ActiveModelSerializers
assert_equal expected_errors_object, result
end
def test_error_document_key_transform_dashed
mock_request(:dashed)
def test_error_document_transform_dash
mock_request(:dash)
resource = ModelWithErrors.new
resource.errors.add(:published_at, 'must be in the future')
@@ -405,7 +405,7 @@ module ActiveModelSerializers
{ :errors =>
[
{
:source => { :pointer => '/data/attributes/published_at' },
:source => { :pointer => '/data/attributes/published-at' },
:detail => 'must be in the future'
},
{
@@ -417,7 +417,7 @@ module ActiveModelSerializers
assert_equal expected_errors_object, result
end
def test_error_document_key_transform_unaltered
def test_error_document_transform_unaltered
mock_request(:unaltered)
resource = ModelWithErrors.new
@@ -438,7 +438,7 @@ module ActiveModelSerializers
assert_equal expected_errors_object, result
end
def test_error_document_key_transform_undefined
def test_error_document_transform_undefined
mock_request(:krazy)
resource = ModelWithErrors.new
@@ -453,7 +453,7 @@ module ActiveModelSerializers
end
end
def test_error_document_key_transform_camel
def test_error_document_transform_camel
mock_request(:camel)
resource = ModelWithErrors.new
@@ -467,14 +467,14 @@ module ActiveModelSerializers
expected_errors_object =
{ :Errors =>
[
{ :Source => { :Pointer => '/data/attributes/published_at' }, :Detail => 'must be in the future' },
{ :Source => { :Pointer => '/data/attributes/title' }, :Detail => 'must be longer' }
{ :Source => { :Pointer => '/data/attributes/PublishedAt' }, :Detail => 'must be in the future' },
{ :Source => { :Pointer => '/data/attributes/Title' }, :Detail => 'must be longer' }
]
}
assert_equal expected_errors_object, result
end
def test_error_document_key_transform_camel_lower
def test_error_document_transform_camel_lower
mock_request(:camel_lower)
resource = ModelWithErrors.new
@@ -488,7 +488,7 @@ module ActiveModelSerializers
expected_errors_object =
{ :errors =>
[
{ :source => { :pointer => '/data/attributes/published_at' }, :detail => 'must be in the future' },
{ :source => { :pointer => '/data/attributes/publishedAt' }, :detail => 'must be in the future' },
{ :source => { :pointer => '/data/attributes/title' }, :detail => 'must be longer' }
]
}

View File

@@ -70,7 +70,8 @@ class ApiAssertion
},
'author' => {
'id' => 42,
'name' => 'Joao Moura.'
'first_name' => 'Joao',
'last_name' => 'Moura'
}
}
}

View File

@@ -0,0 +1,34 @@
require_relative './benchmarking_support'
require_relative './app'
time = 10
disable_gc = true
ActiveModelSerializers.config.key_transform = :unaltered
comments = (0..50).map do |i|
Comment.new(id: i, body: 'ZOMG A COMMENT')
end
author = Author.new(id: 42, first_name: 'Joao', last_name: 'Moura')
post = Post.new(id: 1337, title: 'New Post', blog: nil, body: 'Body', comments: comments, author: author)
serializer = PostSerializer.new(post)
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
serialization = adapter.as_json
Benchmark.ams('camel', time: time, disable_gc: disable_gc) do
ActiveModelSerializers::KeyTransform.camel(serialization)
end
Benchmark.ams('camel_lower', time: time, disable_gc: disable_gc) do
ActiveModelSerializers::KeyTransform.camel_lower(serialization)
end
Benchmark.ams('dash', time: time, disable_gc: disable_gc) do
ActiveModelSerializers::KeyTransform.dash(serialization)
end
Benchmark.ams('unaltered', time: time, disable_gc: disable_gc) do
ActiveModelSerializers::KeyTransform.unaltered(serialization)
end
Benchmark.ams('underscore', time: time, disable_gc: disable_gc) do
ActiveModelSerializers::KeyTransform.underscore(serialization)
end

View File

@@ -8,7 +8,7 @@ class PostController < ActionController::Base
else
comments = [Comment.new(id: 1, body: 'ZOMG A COMMENT')]
end
author = Author.new(id: 42, name: 'Joao Moura.')
author = Author.new(id: 42, first_name: 'Joao', last_name: 'Moura')
Post.new(id: 1337, title: 'New Post', blog: nil, body: 'Body', comments: comments, author: author)
end

View File

@@ -1,6 +1,6 @@
Rails.configuration.serializers = []
class AuthorSerializer < ActiveModel::Serializer
attributes :id, :name
attributes :id, :first_name, :last_name
has_many :posts, embed: :ids
has_one :bio
@@ -27,6 +27,15 @@ class PostSerializer < ActiveModel::Serializer
belongs_to :blog, serializer: BlogSerializer
belongs_to :author, serializer: AuthorSerializer
link(:post_authors) { 'https://example.com/post_authors' }
meta do
{
rating: 5,
favorite_count: 10
}
end
def blog
Blog.new(id: 999, name: 'Custom blog')
end
@@ -34,7 +43,7 @@ end
Rails.configuration.serializers << PostSerializer
class CachingAuthorSerializer < AuthorSerializer
cache key: 'writer', only: [:name], skip_digest: true
cache key: 'writer', only: [:first_name, :last_name], skip_digest: true
end
Rails.configuration.serializers << CachingAuthorSerializer
@@ -63,7 +72,8 @@ if ENV['ENABLE_ACTIVE_RECORD'] == 'true'
t.timestamps null: false
end
create_table :authors, force: true do |t|
t.string :name
t.string :first_name
t.string :last_name
t.timestamps null: false
end
create_table :posts, force: true do |t|
@@ -144,7 +154,7 @@ else
end
class Author < BenchmarkModel
attr_accessor :id, :name, :posts
attr_accessor :id, :first_name, :last_name, :posts
end
class Post < BenchmarkModel