mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-24 06:46:50 +00:00
Allow overriding the adapter with render option
Make it easy to use multiple adapters in an app. use "adapter: false" to not use ams make a test override config.adapter
This commit is contained in:
parent
08fbba9087
commit
5560b49098
@ -6,29 +6,32 @@ module ActionController
|
|||||||
|
|
||||||
include ActionController::Renderers
|
include ActionController::Renderers
|
||||||
|
|
||||||
ADAPTER_OPTION_KEYS = [:include, :root]
|
ADAPTER_OPTION_KEYS = [:include, :root, :adapter]
|
||||||
|
|
||||||
def get_serializer(resource, options)
|
def get_serializer(resource)
|
||||||
@_serializer ||= options.delete(:serializer)
|
@_serializer ||= @_serializer_opts.delete(:serializer)
|
||||||
@_serializer ||= ActiveModel::Serializer.serializer_for(resource)
|
@_serializer ||= ActiveModel::Serializer.serializer_for(resource)
|
||||||
|
|
||||||
if options.key?(:each_serializer)
|
if @_serializer_opts.key?(:each_serializer)
|
||||||
options[:serializer] = options.delete(:each_serializer)
|
@_serializer_opts[:serializer] = @_serializer_opts.delete(:each_serializer)
|
||||||
end
|
end
|
||||||
|
|
||||||
@_serializer
|
@_serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def use_adapter?
|
||||||
|
!(@_adapter_opts.key?(:adapter) && !@_adapter_opts[:adapter])
|
||||||
|
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|
|
||||||
|
@_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 }.map { |h| Hash[h] }
|
||||||
|
|
||||||
if (serializer = get_serializer(resource, serializer_opts))
|
if use_adapter? && (serializer = get_serializer(resource))
|
||||||
# omg hax
|
# omg hax
|
||||||
object = serializer.new(resource, serializer_opts)
|
object = serializer.new(resource, @_serializer_opts)
|
||||||
adapter = ActiveModel::Serializer.adapter.new(object, adapter_opts)
|
adapter = ActiveModel::Serializer::Adapter.create(object, @_adapter_opts)
|
||||||
super(adapter, options)
|
super(adapter, options)
|
||||||
else
|
else
|
||||||
super(resource, options)
|
super(resource, options)
|
||||||
|
|||||||
@ -90,8 +90,7 @@ module ActiveModel
|
|||||||
def self.adapter
|
def self.adapter
|
||||||
adapter_class = case config.adapter
|
adapter_class = case config.adapter
|
||||||
when Symbol
|
when Symbol
|
||||||
class_name = "ActiveModel::Serializer::Adapter::#{config.adapter.to_s.classify}"
|
ActiveModel::Serializer::Adapter.adapter_class(config.adapter)
|
||||||
class_name.safe_constantize
|
|
||||||
when Class
|
when Class
|
||||||
config.adapter
|
config.adapter
|
||||||
end
|
end
|
||||||
|
|||||||
@ -20,6 +20,16 @@ module ActiveModel
|
|||||||
def as_json(options = {})
|
def as_json(options = {})
|
||||||
serializable_hash(options)
|
serializable_hash(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.create(resource, options = {})
|
||||||
|
override = options.delete(:adapter)
|
||||||
|
klass = override ? adapter_class(override) : ActiveModel::Serializer.adapter
|
||||||
|
klass.new(resource, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.adapter_class(adapter)
|
||||||
|
"ActiveModel::Serializer::Adapter::#{adapter.to_s.classify}".safe_constantize
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
41
test/action_controller/adapter_selector_test.rb
Normal file
41
test/action_controller/adapter_selector_test.rb
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
module ActionController
|
||||||
|
module Serialization
|
||||||
|
class AdapterSelectorTest < ActionController::TestCase
|
||||||
|
class MyController < ActionController::Base
|
||||||
|
def render_using_default_adapter
|
||||||
|
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||||
|
render json: @profile
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_using_adapter_override
|
||||||
|
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||||
|
render json: @profile, adapter: :json_api
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_skipping_adapter
|
||||||
|
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||||
|
render json: @profile, adapter: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
tests MyController
|
||||||
|
|
||||||
|
def test_render_using_default_adapter
|
||||||
|
get :render_using_default_adapter
|
||||||
|
assert_equal '{"name":"Name 1","description":"Description 1"}', response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_render_using_adapter_override
|
||||||
|
get :render_using_adapter_override
|
||||||
|
assert_equal '{"profiles":{"name":"Name 1","description":"Description 1"}}', response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_render_skipping_adapter
|
||||||
|
get :render_skipping_adapter
|
||||||
|
assert_equal '{"attributes":{"name":"Name 1","description":"Description 1","comments":"Comments 1"}}', response.body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -28,54 +28,34 @@ module ActionController
|
|||||||
@second_comment.author = nil
|
@second_comment.author = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def with_json_api_adapter
|
|
||||||
old_adapter = ActiveModel::Serializer.config.adapter
|
|
||||||
ActiveModel::Serializer.config.adapter = :json_api
|
|
||||||
yield
|
|
||||||
ensure
|
|
||||||
ActiveModel::Serializer.config.adapter = old_adapter
|
|
||||||
end
|
|
||||||
|
|
||||||
def render_resource_without_include
|
def render_resource_without_include
|
||||||
with_json_api_adapter do
|
setup_post
|
||||||
setup_post
|
render json: @post, adapter: :json_api
|
||||||
render json: @post
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_resource_with_include
|
def render_resource_with_include
|
||||||
with_json_api_adapter do
|
setup_post
|
||||||
setup_post
|
render json: @post, include: 'author', adapter: :json_api
|
||||||
render json: @post, include: 'author'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_resource_with_nested_include
|
def render_resource_with_nested_include
|
||||||
with_json_api_adapter do
|
setup_post
|
||||||
setup_post
|
render json: @post, include: 'comments.author', adapter: :json_api
|
||||||
render json: @post, include: 'comments.author'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_resource_with_nested_has_many_include
|
def render_resource_with_nested_has_many_include
|
||||||
with_json_api_adapter do
|
setup_post
|
||||||
setup_post
|
render json: @post, include: 'author,author.roles', adapter: :json_api
|
||||||
render json: @post, include: 'author,author.roles'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_collection_without_include
|
def render_collection_without_include
|
||||||
with_json_api_adapter do
|
setup_post
|
||||||
setup_post
|
render json: [@post], adapter: :json_api
|
||||||
render json: [@post]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_collection_with_include
|
def render_collection_with_include
|
||||||
with_json_api_adapter do
|
setup_post
|
||||||
setup_post
|
render json: [@post], include: 'author,comments', adapter: :json_api
|
||||||
render json: [@post], include: 'author,comments'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -25,13 +25,9 @@ module ActionController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def render_using_custom_root_in_adapter_with_a_default
|
def render_using_custom_root_in_adapter_with_a_default
|
||||||
old_adapter = ActiveModel::Serializer.config.adapter
|
|
||||||
# JSON-API adapter sets root by default
|
# JSON-API adapter sets root by default
|
||||||
ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::JsonApi
|
|
||||||
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
@profile = Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' })
|
||||||
render json: @profile, root: "profile"
|
render json: @profile, root: "profile", adapter: :json_api
|
||||||
ensure
|
|
||||||
ActiveModel::Serializer.config.adapter = old_adapter
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_array_using_implicit_serializer
|
def render_array_using_implicit_serializer
|
||||||
|
|||||||
@ -18,6 +18,26 @@ module ActiveModel
|
|||||||
def test_serializer
|
def test_serializer
|
||||||
assert_equal @serializer, @adapter.serializer
|
assert_equal @serializer, @adapter.serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_adapter_class_for_known_adapter
|
||||||
|
klass = ActiveModel::Serializer::Adapter.adapter_class(:json_api)
|
||||||
|
assert_equal ActiveModel::Serializer::Adapter::JsonApi, klass
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_adapter_class_for_unknown_adapter
|
||||||
|
klass = ActiveModel::Serializer::Adapter.adapter_class(:json_simple)
|
||||||
|
assert_nil klass
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_adapter
|
||||||
|
adapter = ActiveModel::Serializer::Adapter.create(@serializer)
|
||||||
|
assert_equal ActiveModel::Serializer::Adapter::Json, adapter.class
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create_adapter_with_override
|
||||||
|
adapter = ActiveModel::Serializer::Adapter.create(@serializer, { adapter: :json_api})
|
||||||
|
assert_equal ActiveModel::Serializer::Adapter::JsonApi, adapter.class
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -7,7 +7,7 @@ module ActiveModel
|
|||||||
assert_equal ActiveModel::Serializer::ArraySerializer, ActiveModel::Serializer.config.array_serializer
|
assert_equal ActiveModel::Serializer::ArraySerializer, ActiveModel::Serializer.config.array_serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_adapter
|
def test_default_adapter
|
||||||
assert_equal :json, ActiveModel::Serializer.config.adapter
|
assert_equal :json, ActiveModel::Serializer.config.adapter
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user