mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-24 06:46:50 +00:00
merge upstream update fieldset
This commit is contained in:
commit
2ed52f96a6
@ -1,4 +1,7 @@
|
|||||||
language: ruby
|
language: ruby
|
||||||
|
|
||||||
|
sudo: false
|
||||||
|
|
||||||
rvm:
|
rvm:
|
||||||
- 1.9.3
|
- 1.9.3
|
||||||
- 2.0.0
|
- 2.0.0
|
||||||
@ -6,13 +9,16 @@ rvm:
|
|||||||
- jruby-19mode
|
- jruby-19mode
|
||||||
- rbx-2
|
- rbx-2
|
||||||
- ruby-head
|
- ruby-head
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- bundle install --retry=3
|
- bundle install --retry=3
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- "RAILS_VERSION=3.2"
|
- "RAILS_VERSION=3.2"
|
||||||
- "RAILS_VERSION=4.0"
|
- "RAILS_VERSION=4.0"
|
||||||
- "RAILS_VERSION=4.1"
|
- "RAILS_VERSION=4.1"
|
||||||
- "RAILS_VERSION=master"
|
- "RAILS_VERSION=master"
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- rvm: ruby-head
|
- rvm: ruby-head
|
||||||
|
|||||||
33
README.md
33
README.md
@ -69,6 +69,18 @@ ActiveModel::Serializer.config.adapter = :hal
|
|||||||
You won't need to implement an adapter unless you wish to use a new format or
|
You won't need to implement an adapter unless you wish to use a new format or
|
||||||
media type with AMS.
|
media type with AMS.
|
||||||
|
|
||||||
|
If you would like the key in the outputted JSON to be different from its name in ActiveRecord, you can use the :key option to customize it:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class PostSerializer < ActiveModel::Serializer
|
||||||
|
attributes :id, :body
|
||||||
|
|
||||||
|
# look up :subject on the model, but use +title+ in the JSON
|
||||||
|
attribute :subject, :key => :title
|
||||||
|
has_many :comments
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
In your controllers, when you use `render :json`, Rails will now first search
|
In your controllers, when you use `render :json`, Rails will now first search
|
||||||
for a serializer for the object and use it if available.
|
for a serializer for the object and use it if available.
|
||||||
|
|
||||||
@ -94,6 +106,27 @@ 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
|
||||||
|
# Use the default `ArraySerializer`, which will use `each_serializer` to
|
||||||
|
# serialize each element
|
||||||
|
render json: @posts, each_serializer: PostPreviewSerializer
|
||||||
|
|
||||||
|
# Or, you can explicitly provide the collection serializer as well
|
||||||
|
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:
|
||||||
|
|||||||
@ -6,18 +6,32 @@ module ActionController
|
|||||||
|
|
||||||
include ActionController::Renderers
|
include ActionController::Renderers
|
||||||
|
|
||||||
ADAPTER_OPTION_KEYS = [:include, :fields, :root]
|
ADAPTER_OPTION_KEYS = [:include, :fields, :root, :adapter]
|
||||||
|
|
||||||
|
def get_serializer(resource)
|
||||||
|
@_serializer ||= @_serializer_opts.delete(:serializer)
|
||||||
|
@_serializer ||= ActiveModel::Serializer.serializer_for(resource)
|
||||||
|
|
||||||
|
if @_serializer_opts.key?(:each_serializer)
|
||||||
|
@_serializer_opts[:serializer] = @_serializer_opts.delete(:each_serializer)
|
||||||
|
end
|
||||||
|
|
||||||
|
@_serializer
|
||||||
|
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|
|
||||||
serializer = ActiveModel::Serializer.serializer_for(resource)
|
@_adapter_opts, @_serializer_opts =
|
||||||
|
options.partition { |k, _| ADAPTER_OPTION_KEYS.include? k }.map { |h| Hash[h] }
|
||||||
|
|
||||||
if serializer
|
if use_adapter? && (serializer = get_serializer(resource))
|
||||||
adapter_opts, serializer_opts =
|
|
||||||
options.partition { |k, _| ADAPTER_OPTION_KEYS.include? k }
|
|
||||||
# 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.create(object, @_adapter_opts)
|
||||||
super(adapter, options)
|
super(adapter, options)
|
||||||
else
|
else
|
||||||
super(resource, options)
|
super(resource, options)
|
||||||
|
|||||||
@ -21,7 +21,6 @@ module ActiveModel
|
|||||||
def self.attributes(*attrs)
|
def self.attributes(*attrs)
|
||||||
@_attributes.concat attrs
|
@_attributes.concat attrs
|
||||||
|
|
||||||
|
|
||||||
attrs.each do |attr|
|
attrs.each do |attr|
|
||||||
define_method attr do
|
define_method attr do
|
||||||
object.read_attribute_for_serialization(attr)
|
object.read_attribute_for_serialization(attr)
|
||||||
@ -29,6 +28,14 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.attribute(attr, options = {})
|
||||||
|
key = options.fetch(:key, attr)
|
||||||
|
@_attributes.concat [key]
|
||||||
|
define_method key do
|
||||||
|
object.read_attribute_for_serialization(attr)
|
||||||
|
end unless method_defined?(key)
|
||||||
|
end
|
||||||
|
|
||||||
# Defines an association in the object should be rendered.
|
# Defines an association in the object should be rendered.
|
||||||
#
|
#
|
||||||
# The serializer object should implement the association name
|
# The serializer object should implement the association name
|
||||||
@ -83,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
|
||||||
|
|||||||
@ -25,91 +25,129 @@ module ActiveModel
|
|||||||
else
|
else
|
||||||
@hash[@root] = attributes_for_serializer(serializer, @options)
|
@hash[@root] = attributes_for_serializer(serializer, @options)
|
||||||
|
|
||||||
serializer.each_association do |name, association, opts|
|
add_resource_links(@hash[@root], serializer)
|
||||||
@hash[@root][:links] ||= {}
|
|
||||||
|
|
||||||
if association.respond_to?(:each)
|
|
||||||
add_links(name, association, opts)
|
|
||||||
else
|
|
||||||
add_link(name, association, opts)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@hash
|
@hash
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_links(name, serializers, options)
|
|
||||||
if serializers.first
|
|
||||||
type = serializers.first.object.class.to_s.underscore.pluralize
|
|
||||||
end
|
|
||||||
if name.to_s == type || !type
|
|
||||||
@hash[@root][:links][name] ||= []
|
|
||||||
@hash[@root][:links][name] += serializers.map{|serializer| serializer.id.to_s }
|
|
||||||
else
|
|
||||||
@hash[@root][:links][name] ||= {}
|
|
||||||
@hash[@root][:links][name][:type] = type
|
|
||||||
@hash[@root][:links][name][:ids] ||= []
|
|
||||||
@hash[@root][:links][name][:ids] += serializers.map{|serializer| serializer.id.to_s }
|
|
||||||
end
|
|
||||||
|
|
||||||
unless serializers.none? || @options[:embed] == :ids
|
|
||||||
serializers.each do |serializer|
|
|
||||||
add_linked(name, serializer)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_link(name, serializer, options)
|
|
||||||
if serializer
|
|
||||||
type = serializer.object.class.to_s.underscore
|
|
||||||
if name.to_s == type || !type
|
|
||||||
@hash[@root][:links][name] = serializer.id.to_s
|
|
||||||
else
|
|
||||||
@hash[@root][:links][name] ||= {}
|
|
||||||
@hash[@root][:links][name][:type] = type
|
|
||||||
@hash[@root][:links][name][:id] = serializer.id.to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
unless @options[:embed] == :ids
|
|
||||||
add_linked(name, serializer)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
@hash[@root][:links][name] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_linked(resource, serializer, parent = nil)
|
|
||||||
resource_path = [parent, resource].compact.join('.')
|
|
||||||
if include_assoc? resource_path
|
|
||||||
plural_name = resource.to_s.pluralize.to_sym
|
|
||||||
attrs = attributes_for_serializer(serializer, @options)
|
|
||||||
@top[:linked] ||= {}
|
|
||||||
@top[:linked][plural_name] ||= []
|
|
||||||
@top[:linked][plural_name].push attrs unless @top[:linked][plural_name].include? attrs
|
|
||||||
end
|
|
||||||
|
|
||||||
unless serializer.respond_to?(:each)
|
|
||||||
serializer.each_association do |name, association, opts|
|
|
||||||
add_linked(name, association, resource) if association
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def attributes_for_serializer(serializer, options)
|
def add_links(resource, name, serializers)
|
||||||
if fields = @fieldset && @fieldset.fields_for(serializer)
|
type = serialized_object_type(serializers)
|
||||||
options[:fields] = fields
|
resource[:links] ||= {}
|
||||||
end
|
|
||||||
|
|
||||||
attributes = serializer.attributes(options)
|
if name.to_s == type || !type
|
||||||
attributes[:id] = attributes[:id].to_s if attributes[:id]
|
resource[:links][name] ||= []
|
||||||
attributes
|
resource[:links][name] += serializers.map{|serializer| serializer.id.to_s }
|
||||||
|
else
|
||||||
|
resource[:links][name] ||= {}
|
||||||
|
resource[:links][name][:type] = type
|
||||||
|
resource[:links][name][:ids] ||= []
|
||||||
|
resource[:links][name][:ids] += serializers.map{|serializer| serializer.id.to_s }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_assoc? assoc
|
def add_link(resource, name, serializer)
|
||||||
@options[:include] && @options[:include].split(',').include?(assoc.to_s)
|
resource[:links] ||= {}
|
||||||
|
resource[:links][name] = nil
|
||||||
|
|
||||||
|
if serializer
|
||||||
|
type = serialized_object_type(serializer)
|
||||||
|
if name.to_s == type || !type
|
||||||
|
resource[:links][name] = serializer.id.to_s
|
||||||
|
else
|
||||||
|
resource[:links][name] ||= {}
|
||||||
|
resource[:links][name][:type] = type
|
||||||
|
resource[:links][name][:id] = serializer.id.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_linked(resource_name, serializer, parent = nil)
|
||||||
|
resource_path = [parent, resource_name].compact.join('.')
|
||||||
|
|
||||||
|
if include_assoc?(resource_path)
|
||||||
|
plural_name = serialized_object_type(serializer).pluralize.to_sym
|
||||||
|
attrs = [attributes_for_serializer(serializer, @options)].flatten
|
||||||
|
@top[:linked] ||= {}
|
||||||
|
@top[:linked][plural_name] ||= []
|
||||||
|
|
||||||
|
attrs.each do |attrs|
|
||||||
|
add_resource_links(attrs, serializer, add_linked: false)
|
||||||
|
|
||||||
|
@top[:linked][plural_name].push(attrs) unless @top[:linked][plural_name].include?(attrs)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
serializer.each_association do |name, association, opts|
|
||||||
|
add_linked(name, association, resource_path) if association
|
||||||
|
end if include_nested_assoc? resource_path
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def attributes_for_serializer(serializer, options)
|
||||||
|
if serializer.respond_to?(:each)
|
||||||
|
result = []
|
||||||
|
serializer.each do |object|
|
||||||
|
options[:fields] = @fieldset && @fieldset.fields_for(serializer)
|
||||||
|
attributes = object.attributes(options)
|
||||||
|
attributes[:id] = attributes[:id].to_s if attributes[:id]
|
||||||
|
result << attributes
|
||||||
|
end
|
||||||
|
else
|
||||||
|
options[:fields] = @fieldset && @fieldset.fields_for(serializer)
|
||||||
|
result = serializer.attributes(options)
|
||||||
|
result[:id] = result[:id].to_s if result[:id]
|
||||||
|
end
|
||||||
|
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
def include_assoc?(assoc)
|
||||||
|
return false unless @options[:include]
|
||||||
|
check_assoc("#{assoc}$")
|
||||||
|
end
|
||||||
|
|
||||||
|
def include_nested_assoc?(assoc)
|
||||||
|
return false unless @options[:include]
|
||||||
|
check_assoc("#{assoc}.")
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_assoc(assoc)
|
||||||
|
@options[:include].split(',').any? do |s|
|
||||||
|
s.match(/^#{assoc.gsub('.', '\.')}/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def serialized_object_type(serializer)
|
||||||
|
return false unless Array(serializer).first
|
||||||
|
type_name = Array(serializer).first.object.class.to_s.underscore
|
||||||
|
if serializer.respond_to?(:first)
|
||||||
|
type_name.pluralize
|
||||||
|
else
|
||||||
|
type_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_resource_links(attrs, serializer, options = {})
|
||||||
|
options[:add_linked] = options.fetch(:add_linked, true)
|
||||||
|
|
||||||
|
Array(serializer).first.each_association do |name, association, opts|
|
||||||
|
attrs[:links] ||= {}
|
||||||
|
|
||||||
|
if association.respond_to?(:each)
|
||||||
|
add_links(attrs, name, association)
|
||||||
|
else
|
||||||
|
add_link(attrs, name, association)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @options[:embed] != :ids && options[:add_linked]
|
||||||
|
Array(association).each do |association|
|
||||||
|
add_linked(name, association)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -2,11 +2,13 @@ module ActiveModel
|
|||||||
class Serializer
|
class Serializer
|
||||||
class Fieldset
|
class Fieldset
|
||||||
|
|
||||||
attr_reader :fields, :root
|
|
||||||
|
|
||||||
def initialize(fields, root = nil)
|
def initialize(fields, root = nil)
|
||||||
@root = root
|
@root = root
|
||||||
@fields = parse(fields)
|
@raw_fields = fields
|
||||||
|
end
|
||||||
|
|
||||||
|
def fields
|
||||||
|
@fields ||= parsed_fields
|
||||||
end
|
end
|
||||||
|
|
||||||
def fields_for(serializer)
|
def fields_for(serializer)
|
||||||
@ -16,15 +18,17 @@ module ActiveModel
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def parse(fields)
|
attr_reader :raw_fields, :root
|
||||||
if fields.is_a?(Hash)
|
|
||||||
fields.inject({}) { |h,(k,v)| h[k.to_sym] = v.map(&:to_sym); h}
|
def parsed_fields
|
||||||
elsif fields.is_a?(Array)
|
if raw_fields.is_a?(Hash)
|
||||||
|
raw_fields.inject({}) { |h,(k,v)| h[k.to_sym] = v.map(&:to_sym); h}
|
||||||
|
elsif raw_fields.is_a?(Array)
|
||||||
if root.nil?
|
if root.nil?
|
||||||
raise ArgumentError, 'The root argument must be specified if the fileds argument is an array.'
|
raise ArgumentError, 'The root argument must be specified if the fileds argument is an array.'
|
||||||
end
|
end
|
||||||
hash = {}
|
hash = {}
|
||||||
hash[root.to_sym] = fields.map(&:to_sym)
|
hash[root.to_sym] = raw_fields.map(&:to_sym)
|
||||||
hash
|
hash
|
||||||
else
|
else
|
||||||
{}
|
{}
|
||||||
|
|||||||
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
|
||||||
78
test/action_controller/explicit_serializer_test.rb
Normal file
78
test/action_controller/explicit_serializer_test.rb
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
def render_array_using_implicit_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,
|
||||||
|
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
|
||||||
|
|
||||||
|
def test_render_array_using_explicit_serializer
|
||||||
|
get :render_array_using_implicit_serializer
|
||||||
|
assert_equal 'application/json', @response.content_type
|
||||||
|
|
||||||
|
expected = [
|
||||||
|
{ 'name' => 'Name 1' },
|
||||||
|
{ 'name' => 'Name 2' }
|
||||||
|
]
|
||||||
|
assert_equal expected.to_json, @response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -5,10 +5,18 @@ module ActionController
|
|||||||
class JsonApiLinkedTest < ActionController::TestCase
|
class JsonApiLinkedTest < ActionController::TestCase
|
||||||
class MyController < ActionController::Base
|
class MyController < ActionController::Base
|
||||||
def setup_post
|
def setup_post
|
||||||
|
@role1 = Role.new(id: 1, name: 'admin')
|
||||||
|
@role2 = Role.new(id: 2, name: 'colab')
|
||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
@author.posts = []
|
@author.posts = []
|
||||||
|
@author.bio = nil
|
||||||
|
@author.roles = [@role1, @role2]
|
||||||
|
@role1.author = @author
|
||||||
|
@role2.author = @author
|
||||||
@author2 = Author.new(id: 2, name: 'Anonymous')
|
@author2 = Author.new(id: 2, name: 'Anonymous')
|
||||||
@author2.posts = []
|
@author2.posts = []
|
||||||
|
@author2.bio = nil
|
||||||
|
@author2.roles = []
|
||||||
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
|
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
|
||||||
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||||
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
|
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
|
||||||
@ -20,47 +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
|
|
||||||
|
def render_resource_with_nested_has_many_include
|
||||||
|
setup_post
|
||||||
|
render json: @post, include: 'author,author.roles', adapter: :json_api
|
||||||
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
|
||||||
|
|
||||||
@ -80,6 +75,36 @@ module ActionController
|
|||||||
assert_equal 'Steve K.', response['linked']['authors'].first['name']
|
assert_equal 'Steve K.', response['linked']['authors'].first['name']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_render_resource_with_nested_has_many_include
|
||||||
|
get :render_resource_with_nested_has_many_include
|
||||||
|
response = JSON.parse(@response.body)
|
||||||
|
expected_linked = {
|
||||||
|
"authors" => [{
|
||||||
|
"id" => "1",
|
||||||
|
"name" => "Steve K.",
|
||||||
|
"links" => {
|
||||||
|
"posts" => [],
|
||||||
|
"roles" => ["1", "2"],
|
||||||
|
"bio" => nil
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"roles"=>[{
|
||||||
|
"id" => "1",
|
||||||
|
"name" => "admin",
|
||||||
|
"links" => {
|
||||||
|
"author" => "1"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"id" => "2",
|
||||||
|
"name" => "colab",
|
||||||
|
"links" => {
|
||||||
|
"author" => "1"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
assert_equal expected_linked, response['linked']
|
||||||
|
end
|
||||||
|
|
||||||
def test_render_resource_with_nested_include
|
def test_render_resource_with_nested_include
|
||||||
get :render_resource_with_nested_include
|
get :render_resource_with_nested_include
|
||||||
response = JSON.parse(@response.body)
|
response = JSON.parse(@response.body)
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -7,6 +7,8 @@ module ActiveModel
|
|||||||
class BelongsToTest < Minitest::Test
|
class BelongsToTest < Minitest::Test
|
||||||
def setup
|
def setup
|
||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
|
@author.bio = nil
|
||||||
|
@author.roles = []
|
||||||
@post = Post.new(id: 42, title: 'New Post', body: 'Body')
|
@post = Post.new(id: 42, title: 'New Post', body: 'Body')
|
||||||
@anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
|
@anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
|
||||||
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||||
@ -31,12 +33,28 @@ module ActiveModel
|
|||||||
|
|
||||||
def test_includes_linked_post
|
def test_includes_linked_post
|
||||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'post')
|
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'post')
|
||||||
assert_equal([{id: "42", title: 'New Post', body: 'Body'}], @adapter.serializable_hash[:linked][:posts])
|
expected = [{
|
||||||
|
id: "42",
|
||||||
|
title: 'New Post',
|
||||||
|
body: 'Body',
|
||||||
|
links: {
|
||||||
|
comments: ["1"],
|
||||||
|
author: "1"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
assert_equal expected, @adapter.serializable_hash[:linked][:posts]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_limiting_linked_post_fields
|
def test_limiting_linked_post_fields
|
||||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'post', fields: {post: [:title]})
|
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'post', fields: {post: [:title]})
|
||||||
assert_equal([{title: 'New Post'}], @adapter.serializable_hash[:linked][:posts])
|
expected = [{
|
||||||
|
title: 'New Post',
|
||||||
|
links: {
|
||||||
|
comments: ["1"],
|
||||||
|
author: "1"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
assert_equal expected, @adapter.serializable_hash[:linked][:posts]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_include_nil_author
|
def test_include_nil_author
|
||||||
@ -49,7 +67,53 @@ module ActiveModel
|
|||||||
def test_include_type_for_association_when_is_different_than_name
|
def test_include_type_for_association_when_is_different_than_name
|
||||||
serializer = BlogSerializer.new(@blog)
|
serializer = BlogSerializer.new(@blog)
|
||||||
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
|
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
|
||||||
assert_equal({type: "author", id: "1"}, adapter.serializable_hash[:blogs][:links][:writer])
|
links = adapter.serializable_hash[:blogs][:links]
|
||||||
|
expected = {
|
||||||
|
writer: {
|
||||||
|
type: "author",
|
||||||
|
id: "1"
|
||||||
|
},
|
||||||
|
articles: {
|
||||||
|
type: "posts",
|
||||||
|
ids: ["42", "43"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_equal expected, links
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_include_linked_resources_with_type_name
|
||||||
|
serializer = BlogSerializer.new(@blog)
|
||||||
|
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer, include: "writer,articles")
|
||||||
|
linked = adapter.serializable_hash[:linked]
|
||||||
|
expected = {
|
||||||
|
authors: [{
|
||||||
|
id: "1",
|
||||||
|
name: "Steve K.",
|
||||||
|
links: {
|
||||||
|
posts: [],
|
||||||
|
roles: [],
|
||||||
|
bio: nil
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
posts: [{
|
||||||
|
title: "New Post",
|
||||||
|
body: "Body",
|
||||||
|
id: "42",
|
||||||
|
links: {
|
||||||
|
comments: ["1"],
|
||||||
|
author: "1"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
title: "Hello!!",
|
||||||
|
body: "Hello, world!!",
|
||||||
|
id: "43",
|
||||||
|
links: {
|
||||||
|
comments: [],
|
||||||
|
author: nil
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
assert_equal expected, linked
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -7,6 +7,7 @@ module ActiveModel
|
|||||||
class CollectionTest < Minitest::Test
|
class CollectionTest < Minitest::Test
|
||||||
def setup
|
def setup
|
||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
|
@author.bio = nil
|
||||||
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
||||||
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
||||||
@first_post.comments = []
|
@first_post.comments = []
|
||||||
|
|||||||
@ -7,6 +7,8 @@ module ActiveModel
|
|||||||
class HasManyEmbedIdsTest < Minitest::Test
|
class HasManyEmbedIdsTest < Minitest::Test
|
||||||
def setup
|
def setup
|
||||||
@author = Author.new(name: 'Steve K.')
|
@author = Author.new(name: 'Steve K.')
|
||||||
|
@author.bio = nil
|
||||||
|
@author.roles = nil
|
||||||
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
||||||
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
||||||
@author.posts = [@first_post, @second_post]
|
@author.posts = [@first_post, @second_post]
|
||||||
|
|||||||
@ -8,6 +8,7 @@ module ActiveModel
|
|||||||
def setup
|
def setup
|
||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
@author.posts = []
|
@author.posts = []
|
||||||
|
@author.bio = nil
|
||||||
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
|
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
|
||||||
@post_without_comments = Post.new(id: 2, title: 'Second Post', body: 'Second')
|
@post_without_comments = Post.new(id: 2, title: 'Second Post', body: 'Second')
|
||||||
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||||
@ -34,18 +35,40 @@ module ActiveModel
|
|||||||
|
|
||||||
def test_includes_linked_comments
|
def test_includes_linked_comments
|
||||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'comments')
|
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'comments')
|
||||||
assert_equal([
|
expected = [{
|
||||||
{id: "1", body: 'ZOMG A COMMENT'},
|
id: "1",
|
||||||
{id: "2", body: 'ZOMG ANOTHER COMMENT'}
|
body: 'ZOMG A COMMENT',
|
||||||
], @adapter.serializable_hash[:linked][:comments])
|
links: {
|
||||||
|
post: "1",
|
||||||
|
author: nil
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
id: "2",
|
||||||
|
body: 'ZOMG ANOTHER COMMENT',
|
||||||
|
links: {
|
||||||
|
post: "1",
|
||||||
|
author: nil
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
assert_equal expected, @adapter.serializable_hash[:linked][:comments]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_limit_fields_of_linked_comments
|
def test_limit_fields_of_linked_comments
|
||||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'comments', fields: {comment: [:body]})
|
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'comments', fields: {comment: [:id]})
|
||||||
assert_equal([
|
expected = [{
|
||||||
{body: 'ZOMG A COMMENT'},
|
id: "1",
|
||||||
{body: 'ZOMG ANOTHER COMMENT'}
|
links: {
|
||||||
], @adapter.serializable_hash[:linked][:comments])
|
post: "1",
|
||||||
|
author: nil
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
id: "2",
|
||||||
|
links: {
|
||||||
|
post: "1",
|
||||||
|
author: nil
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
assert_equal expected, @adapter.serializable_hash[:linked][:comments]
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_no_include_linked_if_comments_is_empty
|
def test_no_include_linked_if_comments_is_empty
|
||||||
|
|||||||
@ -7,6 +7,7 @@ module ActiveModel
|
|||||||
class LinkedTest < Minitest::Test
|
class LinkedTest < Minitest::Test
|
||||||
def setup
|
def setup
|
||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
|
@bio = Bio.new(id: 1, content: 'AMS Contributor')
|
||||||
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
||||||
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
||||||
@first_post.comments = []
|
@first_post.comments = []
|
||||||
@ -14,9 +15,12 @@ module ActiveModel
|
|||||||
@first_post.author = @author
|
@first_post.author = @author
|
||||||
@second_post.author = @author
|
@second_post.author = @author
|
||||||
@author.posts = [@first_post, @second_post]
|
@author.posts = [@first_post, @second_post]
|
||||||
|
@author.bio = @bio
|
||||||
|
@author.roles = []
|
||||||
|
@bio.author = @author
|
||||||
|
|
||||||
@serializer = ArraySerializer.new([@first_post, @second_post])
|
@serializer = ArraySerializer.new([@first_post, @second_post])
|
||||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'author,comments')
|
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'author,author.bio,comments')
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_include_multiple_posts_and_linked
|
def test_include_multiple_posts_and_linked
|
||||||
@ -31,7 +35,42 @@ module ActiveModel
|
|||||||
{ title: "Hello!!", body: "Hello, world!!", id: "1", links: { comments: ['1', '2'], author: "1" } },
|
{ title: "Hello!!", body: "Hello, world!!", id: "1", links: { comments: ['1', '2'], author: "1" } },
|
||||||
{ title: "New Post", body: "Body", id: "2", links: { comments: [], :author => "1" } }
|
{ title: "New Post", body: "Body", id: "2", links: { comments: [], :author => "1" } }
|
||||||
], @adapter.serializable_hash[:posts])
|
], @adapter.serializable_hash[:posts])
|
||||||
assert_equal({ :comments => [{ :id => "1", :body => "ZOMG A COMMENT" }, { :id => "2", :body => "ZOMG ANOTHER COMMENT" }], :authors => [{ :id => "1", :name => "Steve K." }] }, @adapter.serializable_hash[:linked])
|
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
comments: [{
|
||||||
|
id: "1",
|
||||||
|
body: "ZOMG A COMMENT",
|
||||||
|
links: {
|
||||||
|
post: "1",
|
||||||
|
author: nil
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
id: "2",
|
||||||
|
body: "ZOMG ANOTHER COMMENT",
|
||||||
|
links: {
|
||||||
|
post: "1",
|
||||||
|
author: nil
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
authors: [{
|
||||||
|
id: "1",
|
||||||
|
name: "Steve K.",
|
||||||
|
links: {
|
||||||
|
posts: ["1", "2"],
|
||||||
|
roles: [],
|
||||||
|
bio: "1"
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
bios: [{
|
||||||
|
id: "1",
|
||||||
|
content: "AMS Contributor",
|
||||||
|
links: {
|
||||||
|
author: "1"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
assert_equal expected, @adapter.serializable_hash[:linked]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
33
test/fixtures/poro.rb
vendored
33
test/fixtures/poro.rb
vendored
@ -35,10 +35,18 @@ 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)
|
||||||
|
Bio = Class.new(Model)
|
||||||
Blog = Class.new(Model)
|
Blog = Class.new(Model)
|
||||||
|
Role = Class.new(Model)
|
||||||
|
|
||||||
PostSerializer = Class.new(ActiveModel::Serializer) do
|
PostSerializer = Class.new(ActiveModel::Serializer) do
|
||||||
attributes :title, :body, :id
|
attributes :title, :body, :id
|
||||||
@ -59,6 +67,20 @@ AuthorSerializer = Class.new(ActiveModel::Serializer) do
|
|||||||
attributes :id, :name
|
attributes :id, :name
|
||||||
|
|
||||||
has_many :posts, embed: :ids
|
has_many :posts, embed: :ids
|
||||||
|
has_many :roles, embed: :ids
|
||||||
|
belongs_to :bio
|
||||||
|
end
|
||||||
|
|
||||||
|
RoleSerializer = Class.new(ActiveModel::Serializer) do
|
||||||
|
attributes :id, :name
|
||||||
|
|
||||||
|
belongs_to :author
|
||||||
|
end
|
||||||
|
|
||||||
|
BioSerializer = Class.new(ActiveModel::Serializer) do
|
||||||
|
attributes :id, :content
|
||||||
|
|
||||||
|
belongs_to :author
|
||||||
end
|
end
|
||||||
|
|
||||||
BlogSerializer = Class.new(ActiveModel::Serializer) do
|
BlogSerializer = Class.new(ActiveModel::Serializer) do
|
||||||
@ -67,3 +89,14 @@ 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
|
||||||
|
|
||||||
|
AlternateBlogSerializer = Class.new(ActiveModel::Serializer) do
|
||||||
|
attribute :id
|
||||||
|
attribute :name, key: :title
|
||||||
|
end
|
||||||
|
|||||||
@ -26,6 +26,8 @@ module ActiveModel
|
|||||||
|
|
||||||
def setup
|
def setup
|
||||||
@author = Author.new(name: 'Steve K.')
|
@author = Author.new(name: 'Steve K.')
|
||||||
|
@author.bio = nil
|
||||||
|
@author.roles = []
|
||||||
@post = Post.new({ title: 'New Post', body: 'Body' })
|
@post = Post.new({ title: 'New Post', body: 'Body' })
|
||||||
@comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
|
@comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
|
||||||
@post.comments = [@comment]
|
@post.comments = [@comment]
|
||||||
@ -39,11 +41,25 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_has_many
|
def test_has_many
|
||||||
assert_equal({posts: {type: :has_many, options: {embed: :ids}}}, @author_serializer.class._associations)
|
assert_equal(
|
||||||
|
{ posts: { type: :has_many, options: { embed: :ids } },
|
||||||
|
roles: { type: :has_many, options: { embed: :ids } },
|
||||||
|
bio: { type: :belongs_to, options: {} } },
|
||||||
|
@author_serializer.class._associations
|
||||||
|
)
|
||||||
@author_serializer.each_association do |name, serializer, options|
|
@author_serializer.each_association do |name, serializer, options|
|
||||||
assert_equal(:posts, name)
|
if name == :posts
|
||||||
assert_equal({embed: :ids}, options)
|
assert_equal({embed: :ids}, options)
|
||||||
assert_kind_of(ActiveModel::Serializer.config.array_serializer, serializer)
|
assert_kind_of(ActiveModel::Serializer.config.array_serializer, serializer)
|
||||||
|
elsif name == :bio
|
||||||
|
assert_equal({}, options)
|
||||||
|
assert_nil serializer
|
||||||
|
elsif name == :roles
|
||||||
|
assert_equal({embed: :ids}, options)
|
||||||
|
assert_kind_of(ActiveModel::Serializer.config.array_serializer, serializer)
|
||||||
|
else
|
||||||
|
flunk "Unknown association: #{name}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
23
test/serializers/attribute_test.rb
Normal file
23
test/serializers/attribute_test.rb
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
module ActiveModel
|
||||||
|
class Serializer
|
||||||
|
class AttributeTest < Minitest::Test
|
||||||
|
def setup
|
||||||
|
@blog = Blog.new({ id: 1, name: 'AMS Hints' })
|
||||||
|
@blog_serializer = AlternateBlogSerializer.new(@blog)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_attributes_definition
|
||||||
|
assert_equal([:id, :title],
|
||||||
|
@blog_serializer.class._attributes)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_json_serializable_hash
|
||||||
|
adapter = ActiveModel::Serializer::Adapter::Json.new(@blog_serializer)
|
||||||
|
assert_equal({:id=>1, :title=>"AMS Hints"}, adapter.serializable_hash)
|
||||||
|
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