mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-22 22:06:50 +00:00
Support serializer and each_serializer in render json
This commit is contained in:
parent
95d122046d
commit
c84430cdad
16
README.md
16
README.md
@ -94,6 +94,22 @@ member when the resource names are included in the `include` option.
|
|||||||
render @posts, include: 'authors,comments'
|
render @posts, include: 'authors,comments'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Specify a serializer
|
||||||
|
|
||||||
|
If you wish to use a serializer other than the default, you can explicitly pass it to the renderer.
|
||||||
|
|
||||||
|
#### 1. For a resource:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
render json: @post, serializer: PostPreviewSerializer
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. For an array resource:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
render json: @posts, serializer: PaginatedSerializer, each_serializer: PostPreviewSerializer
|
||||||
|
```
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Add this line to your application's Gemfile:
|
Add this line to your application's Gemfile:
|
||||||
|
|||||||
@ -8,16 +8,25 @@ module ActionController
|
|||||||
|
|
||||||
ADAPTER_OPTION_KEYS = [:include, :root]
|
ADAPTER_OPTION_KEYS = [:include, :root]
|
||||||
|
|
||||||
|
def get_serializer(resource, options)
|
||||||
|
@_serializer ||= if (serializer = options.delete :serializer)
|
||||||
|
options[:serializer] = options.delete :each_serializer
|
||||||
|
serializer
|
||||||
|
else
|
||||||
|
ActiveModel::Serializer.serializer_for(resource)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
[:_render_option_json, :_render_with_renderer_json].each do |renderer_method|
|
[:_render_option_json, :_render_with_renderer_json].each do |renderer_method|
|
||||||
define_method renderer_method do |resource, options|
|
define_method renderer_method do |resource, options|
|
||||||
serializer = ActiveModel::Serializer.serializer_for(resource)
|
|
||||||
|
|
||||||
if serializer
|
adapter_opts, serializer_opts =
|
||||||
adapter_opts, serializer_opts =
|
options.partition { |k, _| ADAPTER_OPTION_KEYS.include? k }.map { |h| Hash[h] }
|
||||||
options.partition { |k, _| ADAPTER_OPTION_KEYS.include? k }
|
|
||||||
|
if (serializer = get_serializer(resource, serializer_opts))
|
||||||
# omg hax
|
# omg hax
|
||||||
object = serializer.new(resource, Hash[serializer_opts])
|
object = serializer.new(resource, serializer_opts)
|
||||||
adapter = ActiveModel::Serializer.adapter.new(object, Hash[adapter_opts])
|
adapter = ActiveModel::Serializer.adapter.new(object, adapter_opts)
|
||||||
super(adapter, options)
|
super(adapter, options)
|
||||||
else
|
else
|
||||||
super(resource, options)
|
super(resource, options)
|
||||||
|
|||||||
@ -6,7 +6,10 @@ module ActiveModel
|
|||||||
|
|
||||||
def initialize(objects, options = {})
|
def initialize(objects, options = {})
|
||||||
@objects = objects.map do |object|
|
@objects = objects.map do |object|
|
||||||
serializer_class = ActiveModel::Serializer.serializer_for(object)
|
serializer_class = options.fetch(
|
||||||
|
:serializer,
|
||||||
|
ActiveModel::Serializer.serializer_for(object)
|
||||||
|
)
|
||||||
serializer_class.new(object)
|
serializer_class.new(object)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
53
test/action_controller/explicit_serializer_test.rb
Normal file
53
test/action_controller/explicit_serializer_test.rb
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
module ActionController
|
||||||
|
module Serialization
|
||||||
|
class ExplicitSerializerTest < ActionController::TestCase
|
||||||
|
class MyController < ActionController::Base
|
||||||
|
def render_using_explicit_serializer
|
||||||
|
@profile = Profile.new(name: 'Name 1',
|
||||||
|
description: 'Description 1',
|
||||||
|
comments: 'Comments 1')
|
||||||
|
render json: @profile, serializer: ProfilePreviewSerializer
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_array_using_explicit_serializer
|
||||||
|
array = [
|
||||||
|
Profile.new(name: 'Name 1',
|
||||||
|
description: 'Description 1',
|
||||||
|
comments: 'Comments 1'),
|
||||||
|
Profile.new(name: 'Name 2',
|
||||||
|
description: 'Description 2',
|
||||||
|
comments: 'Comments 2')
|
||||||
|
]
|
||||||
|
render json: array,
|
||||||
|
serializer: PaginatedSerializer,
|
||||||
|
each_serializer: ProfilePreviewSerializer
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
tests MyController
|
||||||
|
|
||||||
|
def test_render_using_explicit_serializer
|
||||||
|
get :render_using_explicit_serializer
|
||||||
|
|
||||||
|
assert_equal 'application/json', @response.content_type
|
||||||
|
assert_equal '{"name":"Name 1"}', @response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_render_array_using_explicit_serializer
|
||||||
|
get :render_array_using_explicit_serializer
|
||||||
|
assert_equal 'application/json', @response.content_type
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
'paginated' => [
|
||||||
|
{ 'name' => 'Name 1' },
|
||||||
|
{ 'name' => 'Name 2' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal expected.to_json, @response.body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
12
test/fixtures/poro.rb
vendored
12
test/fixtures/poro.rb
vendored
@ -35,6 +35,12 @@ class ProfileSerializer < ActiveModel::Serializer
|
|||||||
urls :posts, :comments
|
urls :posts, :comments
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class ProfilePreviewSerializer < ActiveModel::Serializer
|
||||||
|
attributes :name
|
||||||
|
|
||||||
|
urls :posts, :comments
|
||||||
|
end
|
||||||
|
|
||||||
Post = Class.new(Model)
|
Post = Class.new(Model)
|
||||||
Comment = Class.new(Model)
|
Comment = Class.new(Model)
|
||||||
Author = Class.new(Model)
|
Author = Class.new(Model)
|
||||||
@ -67,3 +73,9 @@ BlogSerializer = Class.new(ActiveModel::Serializer) do
|
|||||||
belongs_to :writer
|
belongs_to :writer
|
||||||
has_many :articles
|
has_many :articles
|
||||||
end
|
end
|
||||||
|
|
||||||
|
PaginatedSerializer = Class.new(ActiveModel::Serializer::ArraySerializer) do
|
||||||
|
def json_key
|
||||||
|
'paginated'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user