mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-23 06:16:50 +00:00
merge upstream/master
This commit is contained in:
commit
c9c58e31e5
2
.gitignore
vendored
2
.gitignore
vendored
@ -16,4 +16,4 @@ test/tmp
|
||||
test/version_tmp
|
||||
tmp
|
||||
*.swp
|
||||
.ruby-version
|
||||
.ruby-version
|
||||
|
||||
@ -6,6 +6,8 @@ rvm:
|
||||
- jruby-19mode
|
||||
- rbx-2
|
||||
- ruby-head
|
||||
install:
|
||||
- bundle install --retry=3
|
||||
env:
|
||||
- "RAILS_VERSION=3.2"
|
||||
- "RAILS_VERSION=4.0"
|
||||
|
||||
67
README.md
67
README.md
@ -1,8 +1,8 @@
|
||||
# ActiveModel::Serializers
|
||||
|
||||
# ActiveModel::Serializers
|
||||
|
||||
[](https://travis-ci.org/rails-api/active_model_serializers)
|
||||
|
||||
ActiveModel::Serializers brings convention over configuration to your JSON generation.
|
||||
ActiveModel::Serializers brings convention over configuration to your JSON generation.
|
||||
|
||||
AMS does this through two components: **serializers** and **adapters**. Serializers describe which attributes and relationships should be serialized. Adapters describe how attributes and relationships should be serialized.
|
||||
|
||||
@ -32,7 +32,7 @@ serializers:
|
||||
```ruby
|
||||
class PostSerializer < ActiveModel::Serializer
|
||||
attributes :title, :body
|
||||
|
||||
|
||||
has_many :comments
|
||||
|
||||
url :post
|
||||
@ -61,7 +61,7 @@ ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::HalAd
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
|
||||
```ruby
|
||||
ActiveModel::Serializer.config.adapter = :hal
|
||||
```
|
||||
@ -85,18 +85,27 @@ end
|
||||
In this case, Rails will look for a serializer named `PostSerializer`, and if
|
||||
it exists, use it to serialize the `Post`.
|
||||
|
||||
## Installation
|
||||
|
||||
Add this line to your application's Gemfile:
|
||||
### Built in Adapters
|
||||
|
||||
```
|
||||
gem 'active_model_serializers'
|
||||
The `:json_api` adapter will include the associated resources in the `"linked"`
|
||||
member when the resource names are included in the `include` option.
|
||||
|
||||
```ruby
|
||||
render @posts, include: 'authors,comments'
|
||||
```
|
||||
|
||||
And then execute:
|
||||
|
||||
```
|
||||
$ bundle
|
||||
## Installation
|
||||
|
||||
Add this line to your application's Gemfile:
|
||||
|
||||
```
|
||||
gem 'active_model_serializers'
|
||||
```
|
||||
|
||||
And then execute:
|
||||
|
||||
```
|
||||
$ bundle
|
||||
```
|
||||
|
||||
## Creating a Serializer
|
||||
@ -141,29 +150,27 @@ class CommentSerializer < ActiveModel::Serializer
|
||||
end
|
||||
```
|
||||
|
||||
The attribute names are a **whitelist** of attributes to be serialized.
|
||||
|
||||
The attribute names are a **whitelist** of attributes to be serialized.
|
||||
|
||||
The `has_many` and `belongs_to` declarations describe relationships between
|
||||
resources. By default, when you serialize a `Post`, you will
|
||||
get its `Comment`s as well.
|
||||
resources. By default, when you serialize a `Post`, you will get its `Comment`s
|
||||
as well.
|
||||
|
||||
The `url` declaration describes which named routes to use while generating URLs
|
||||
for your JSON. Not every adapter will require URLs.
|
||||
|
||||
## Getting Help
|
||||
|
||||
If you find a bug, please report an
|
||||
[Issue](https://github.com/rails-api/active_model_serializers/issues/new).
|
||||
If you find a bug, please report an [Issue](https://github.com/rails-api/active_model_serializers/issues/new).
|
||||
|
||||
If you have a question, please [post to Stack
|
||||
Overflow](http://stackoverflow.com/questions/tagged/active-model-serializers).
|
||||
If you have a question, please [post to Stack Overflow](http://stackoverflow.com/questions/tagged/active-model-serializers).
|
||||
|
||||
Thanks!
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork it ( https://github.com/rails-api/active_model_serializers/fork )
|
||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||
4. Push to the branch (`git push origin my-new-feature`)
|
||||
5. Create a new Pull Request
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork it ( https://github.com/rails-api/active_model_serializers/fork )
|
||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||
4. Push to the branch (`git push origin my-new-feature`)
|
||||
5. Create a new Pull Request
|
||||
|
||||
@ -6,15 +6,18 @@ module ActionController
|
||||
|
||||
include ActionController::Renderers
|
||||
|
||||
ADAPTER_OPTION_KEYS = [:include, :root]
|
||||
|
||||
[:_render_option_json, :_render_with_renderer_json].each do |renderer_method|
|
||||
define_method renderer_method do |resource, options|
|
||||
serializer = ActiveModel::Serializer.serializer_for(resource)
|
||||
|
||||
if serializer
|
||||
adapter_opts, serializer_opts =
|
||||
options.partition { |k, _| ADAPTER_OPTION_KEYS.include? k }
|
||||
# omg hax
|
||||
object = serializer.new(resource, options)
|
||||
adapter = ActiveModel::Serializer.adapter.new(object)
|
||||
|
||||
object = serializer.new(resource, Hash[serializer_opts])
|
||||
adapter = ActiveModel::Serializer.adapter.new(object, Hash[adapter_opts])
|
||||
super(adapter, options)
|
||||
else
|
||||
super(resource, options)
|
||||
@ -23,4 +26,3 @@ module ActionController
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -140,7 +140,7 @@ module ActiveModel
|
||||
self.class._associations.dup.each do |name, options|
|
||||
association = object.send(name)
|
||||
serializer_class = ActiveModel::Serializer.serializer_for(association)
|
||||
serializer = serializer_class.new(association)
|
||||
serializer = serializer_class.new(association) if serializer_class
|
||||
|
||||
if block_given?
|
||||
block.call(name, serializer, options[:options])
|
||||
|
||||
@ -10,13 +10,14 @@ module ActiveModel
|
||||
|
||||
def initialize(serializer, options = {})
|
||||
@serializer = serializer
|
||||
@options = options
|
||||
end
|
||||
|
||||
def serializable_hash(options = {})
|
||||
raise NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
|
||||
end
|
||||
|
||||
def to_json(options = {})
|
||||
def as_json(options = {})
|
||||
if fields = options.delete(:fields)
|
||||
options[:fieldset] = ActiveModel::Serializer::Fieldset.new(fields, serializer.json_key)
|
||||
end
|
||||
|
||||
@ -13,7 +13,11 @@ module ActiveModel
|
||||
array_serializer = association
|
||||
@result[name] = array_serializer.map { |item| item.attributes(opts) }
|
||||
else
|
||||
@result[name] = association.attributes(options)
|
||||
if association
|
||||
@result[name] = association.attributes(options)
|
||||
else
|
||||
@result[name] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,25 +5,23 @@ module ActiveModel
|
||||
def initialize(serializer, options = {})
|
||||
super
|
||||
serializer.root = true
|
||||
@hash = {}
|
||||
@top = @options.fetch(:top) { @hash }
|
||||
end
|
||||
|
||||
def serializable_hash(options = {})
|
||||
@root = (options[:root] || serializer.json_key).to_s.pluralize.to_sym
|
||||
@hash = {}
|
||||
@root = (@options[:root] || serializer.json_key.to_s.pluralize).to_sym
|
||||
@fieldset = options[:fieldset]
|
||||
|
||||
if serializer.respond_to?(:each)
|
||||
opt = @fieldset ? {fieldset: @fieldset} : {}
|
||||
|
||||
@hash[@root] = serializer.map{|s| self.class.new(s).serializable_hash(opt)[@root] }
|
||||
@hash[@root] = serializer.map do |s|
|
||||
self.class.new(s, @options.merge(top: @top)).serializable_hash[@root]
|
||||
end
|
||||
else
|
||||
@hash[@root] = attributes_for_serializer(serializer, {})
|
||||
@hash[@root] = attributes_for_serializer(serializer, @options)
|
||||
|
||||
serializer.each_association do |name, association, opts|
|
||||
@hash[@root][:links] ||= {}
|
||||
unless options[:embed] == :ids
|
||||
@hash[:linked] ||= {}
|
||||
end
|
||||
|
||||
if association.respond_to?(:each)
|
||||
add_links(name, association, opts)
|
||||
@ -37,23 +35,59 @@ module ActiveModel
|
||||
end
|
||||
|
||||
def add_links(name, serializers, options)
|
||||
@hash[@root][:links][name] ||= []
|
||||
@hash[@root][:links][name] += serializers.map{|serializer| serializer.id.to_s }
|
||||
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 options[:embed] == :ids
|
||||
@hash[:linked][name] ||= []
|
||||
@hash[:linked][name] += serializers.map { |item| attributes_for_serializer(item, options) }
|
||||
unless serializers.none? || @options[:embed] == :ids
|
||||
serializers.each do |serializer|
|
||||
add_linked(name, serializer)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_link(name, serializer, options)
|
||||
@hash[@root][:links][name] = serializer.id.to_s
|
||||
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
|
||||
plural_name = name.to_s.pluralize.to_sym
|
||||
unless @options[:embed] == :ids
|
||||
add_linked(name, serializer)
|
||||
end
|
||||
else
|
||||
@hash[@root][:links][name] = nil
|
||||
end
|
||||
end
|
||||
|
||||
@hash[:linked][plural_name] ||= []
|
||||
@hash[:linked][plural_name].push attributes_for_serializer(serializer, options)
|
||||
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
|
||||
|
||||
@ -69,6 +103,10 @@ module ActiveModel
|
||||
attributes[:id] = attributes[:id].to_s if attributes[:id]
|
||||
attributes
|
||||
end
|
||||
|
||||
def include_assoc? assoc
|
||||
@options[:include] && @options[:include].split(',').include?(assoc.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
104
test/action_controller/json_api_linked_test.rb
Normal file
104
test/action_controller/json_api_linked_test.rb
Normal file
@ -0,0 +1,104 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActionController
|
||||
module Serialization
|
||||
class JsonApiLinkedTest < ActionController::TestCase
|
||||
class MyController < ActionController::Base
|
||||
def setup_post
|
||||
@author = Author.new(id: 1, name: 'Steve K.')
|
||||
@author.posts = []
|
||||
@author2 = Author.new(id: 2, name: 'Anonymous')
|
||||
@author2.posts = []
|
||||
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
|
||||
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
|
||||
@post.comments = [@first_comment, @second_comment]
|
||||
@post.author = @author
|
||||
@first_comment.post = @post
|
||||
@first_comment.author = @author2
|
||||
@second_comment.post = @post
|
||||
@second_comment.author = nil
|
||||
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
|
||||
with_json_api_adapter do
|
||||
setup_post
|
||||
render json: @post
|
||||
end
|
||||
end
|
||||
|
||||
def render_resource_with_include
|
||||
with_json_api_adapter do
|
||||
setup_post
|
||||
render json: @post, include: 'author'
|
||||
end
|
||||
end
|
||||
|
||||
def render_resource_with_nested_include
|
||||
with_json_api_adapter do
|
||||
setup_post
|
||||
render json: @post, include: 'comments.author'
|
||||
end
|
||||
end
|
||||
|
||||
def render_collection_without_include
|
||||
with_json_api_adapter do
|
||||
setup_post
|
||||
render json: [@post]
|
||||
end
|
||||
end
|
||||
|
||||
def render_collection_with_include
|
||||
with_json_api_adapter do
|
||||
setup_post
|
||||
render json: [@post], include: 'author,comments'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tests MyController
|
||||
|
||||
def test_render_resource_without_include
|
||||
get :render_resource_without_include
|
||||
response = JSON.parse(@response.body)
|
||||
refute response.key? 'linked'
|
||||
end
|
||||
|
||||
def test_render_resource_with_include
|
||||
get :render_resource_with_include
|
||||
response = JSON.parse(@response.body)
|
||||
assert response.key? 'linked'
|
||||
assert_equal 1, response['linked']['authors'].size
|
||||
assert_equal 'Steve K.', response['linked']['authors'].first['name']
|
||||
end
|
||||
|
||||
def test_render_resource_with_nested_include
|
||||
get :render_resource_with_nested_include
|
||||
response = JSON.parse(@response.body)
|
||||
assert response.key? 'linked'
|
||||
assert_equal 1, response['linked']['authors'].size
|
||||
assert_equal 'Anonymous', response['linked']['authors'].first['name']
|
||||
end
|
||||
|
||||
def test_render_collection_without_include
|
||||
get :render_collection_without_include
|
||||
response = JSON.parse(@response.body)
|
||||
refute response.key? 'linked'
|
||||
end
|
||||
|
||||
def test_render_collection_with_include
|
||||
get :render_collection_with_include
|
||||
response = JSON.parse(@response.body)
|
||||
assert response.key? 'linked'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -24,6 +24,16 @@ module ActionController
|
||||
ActiveModel::Serializer.config.adapter = old_adapter
|
||||
end
|
||||
|
||||
def render_using_custom_root_in_adapter_with_a_default
|
||||
old_adapter = ActiveModel::Serializer.config.adapter
|
||||
# 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' })
|
||||
render json: @profile, root: "profile"
|
||||
ensure
|
||||
ActiveModel::Serializer.config.adapter = old_adapter
|
||||
end
|
||||
|
||||
def render_array_using_implicit_serializer
|
||||
array = [
|
||||
Profile.new({ name: 'Name 1', description: 'Description 1', comments: 'Comments 1' }),
|
||||
@ -57,6 +67,13 @@ module ActionController
|
||||
assert_equal '{"profiles":{"name":"Name 1","description":"Description 1"}}', @response.body
|
||||
end
|
||||
|
||||
def test_render_using_custom_root_in_adapter_with_a_default
|
||||
get :render_using_custom_root_in_adapter_with_a_default
|
||||
|
||||
assert_equal 'application/json', @response.content_type
|
||||
assert_equal '{"profile":{"name":"Name 1","description":"Description 1"}}', @response.body
|
||||
end
|
||||
|
||||
def test_render_array_using_implicit_serializer
|
||||
get :render_array_using_implicit_serializer
|
||||
assert_equal 'application/json', @response.content_type
|
||||
|
||||
@ -7,9 +7,14 @@ module ActiveModel
|
||||
class BelongsToTest < Minitest::Test
|
||||
def setup
|
||||
@post = Post.new(id: 42, title: 'New Post', body: 'Body')
|
||||
@anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
|
||||
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||
@post.comments = [@comment]
|
||||
@anonymous_post.comments = []
|
||||
@post.author = @author
|
||||
@comment.post = @post
|
||||
@comment.author = nil
|
||||
@anonymous_post.author = nil
|
||||
|
||||
@serializer = CommentSerializer.new(@comment)
|
||||
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
|
||||
@ -18,6 +23,13 @@ module ActiveModel
|
||||
def test_includes_post
|
||||
assert_equal({id: 42, title: 'New Post', body: 'Body'}, @adapter.serializable_hash[:post])
|
||||
end
|
||||
|
||||
def test_include_nil_author
|
||||
serializer = PostSerializer.new(@anonymous_post)
|
||||
adapter = ActiveModel::Serializer::Adapter::Json.new(serializer)
|
||||
|
||||
assert_equal({title: "Hello!!", body: "Hello, world!!", id: 43, comments: [], author: nil}, adapter.serializable_hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -6,10 +6,13 @@ module ActiveModel
|
||||
class Json
|
||||
class Collection < Minitest::Test
|
||||
def setup
|
||||
@author = Author.new(id: 1, name: 'Steve K.')
|
||||
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
||||
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
||||
@first_post.comments = []
|
||||
@second_post.comments = []
|
||||
@first_post.author = @author
|
||||
@second_post.author = @author
|
||||
|
||||
@serializer = ArraySerializer.new([@first_post, @second_post])
|
||||
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
|
||||
@ -17,8 +20,8 @@ module ActiveModel
|
||||
|
||||
def test_include_multiple_posts
|
||||
assert_equal([
|
||||
{title: "Hello!!", body: "Hello, world!!", id: 1, comments: []},
|
||||
{title: "New Post", body: "Body", id: 2, comments: []}
|
||||
{title: "Hello!!", body: "Hello, world!!", id: 1, comments: [], author: {id: 1, name: "Steve K."}},
|
||||
{title: "New Post", body: "Body", id: 2, comments: [], author: {id: 1, name: "Steve K."}}
|
||||
], @adapter.serializable_hash)
|
||||
end
|
||||
end
|
||||
|
||||
@ -6,10 +6,12 @@ module ActiveModel
|
||||
class Json
|
||||
class HasManyTestTest < Minitest::Test
|
||||
def setup
|
||||
@author = Author.new(id: 1, name: 'Steve K.')
|
||||
@post = Post.new(title: 'New Post', body: 'Body')
|
||||
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
|
||||
@post.comments = [@first_comment, @second_comment]
|
||||
@post.author = @author
|
||||
@first_comment.post = @post
|
||||
@second_comment.post = @post
|
||||
|
||||
|
||||
@ -6,10 +6,20 @@ module ActiveModel
|
||||
class JsonApi
|
||||
class BelongsToTest < Minitest::Test
|
||||
def setup
|
||||
@author = Author.new(id: 1, name: 'Steve K.')
|
||||
@post = Post.new(id: 42, title: 'New Post', body: 'Body')
|
||||
@anonymous_post = Post.new(id: 43, title: 'Hello!!', body: 'Hello, world!!')
|
||||
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||
@post.comments = [@comment]
|
||||
@anonymous_post.comments = []
|
||||
@comment.post = @post
|
||||
@comment.author = nil
|
||||
@post.author = @author
|
||||
@anonymous_post.author = nil
|
||||
@blog = Blog.new(id: 1, name: "My Blog!!")
|
||||
@blog.writer = @author
|
||||
@blog.articles = [@post, @anonymous_post]
|
||||
@author.posts = []
|
||||
|
||||
@serializer = CommentSerializer.new(@comment)
|
||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)
|
||||
@ -20,8 +30,22 @@ module ActiveModel
|
||||
end
|
||||
|
||||
def test_includes_linked_post
|
||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'post')
|
||||
assert_equal([{id: "42", title: 'New Post', body: 'Body'}], @adapter.serializable_hash[:linked][:posts])
|
||||
end
|
||||
|
||||
def test_include_nil_author
|
||||
serializer = PostSerializer.new(@anonymous_post)
|
||||
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
|
||||
|
||||
assert_equal({comments: [], author: nil}, adapter.serializable_hash[:posts][:links])
|
||||
end
|
||||
|
||||
def test_include_type_for_association_when_is_different_than_name
|
||||
serializer = BlogSerializer.new(@blog)
|
||||
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
|
||||
assert_equal({type: "author", id: "1"}, adapter.serializable_hash[:blogs][:links][:writer])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -4,12 +4,16 @@ module ActiveModel
|
||||
class Serializer
|
||||
class Adapter
|
||||
class JsonApi
|
||||
class Collection < Minitest::Test
|
||||
class CollectionTest < Minitest::Test
|
||||
def setup
|
||||
@author = Author.new(id: 1, name: 'Steve K.')
|
||||
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
||||
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
||||
@first_post.comments = []
|
||||
@second_post.comments = []
|
||||
@first_post.author = @author
|
||||
@second_post.author = @author
|
||||
@author.posts = [@first_post, @second_post]
|
||||
|
||||
@serializer = ArraySerializer.new([@first_post, @second_post])
|
||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)
|
||||
@ -17,8 +21,8 @@ module ActiveModel
|
||||
|
||||
def test_include_multiple_posts
|
||||
assert_equal([
|
||||
{title: "Hello!!", body: "Hello, world!!", id: "1", links: {comments: []}},
|
||||
{title: "New Post", body: "Body", id: "2", links: {comments: []}}
|
||||
{ title: "Hello!!", body: "Hello, world!!", id: "1", links: { comments: [], author: "1" } },
|
||||
{ title: "New Post", body: "Body", id: "2", links: { comments: [], author: "1" } }
|
||||
], @adapter.serializable_hash[:posts])
|
||||
end
|
||||
end
|
||||
|
||||
@ -12,6 +12,8 @@ module ActiveModel
|
||||
@author.posts = [@first_post, @second_post]
|
||||
@first_post.author = @author
|
||||
@second_post.author = @author
|
||||
@first_post.comments = []
|
||||
@second_post.comments = []
|
||||
|
||||
@serializer = AuthorSerializer.new(@author)
|
||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)
|
||||
@ -6,12 +6,23 @@ module ActiveModel
|
||||
class JsonApi
|
||||
class HasManyTest < Minitest::Test
|
||||
def setup
|
||||
@post = Post.new(title: 'New Post', body: 'Body')
|
||||
@author = Author.new(id: 1, name: 'Steve K.')
|
||||
@author.posts = []
|
||||
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
|
||||
@post_without_comments = Post.new(id: 2, title: 'Second Post', body: 'Second')
|
||||
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||
@first_comment.author = nil
|
||||
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
|
||||
@second_comment.author = nil
|
||||
@post.comments = [@first_comment, @second_comment]
|
||||
@post_without_comments.comments = []
|
||||
@first_comment.post = @post
|
||||
@second_comment.post = @post
|
||||
@post.author = @author
|
||||
@post_without_comments.author = nil
|
||||
@blog = Blog.new(id: 1, name: "My Blog!!")
|
||||
@blog.writer = @author
|
||||
@blog.articles = [@post]
|
||||
|
||||
@serializer = PostSerializer.new(@post)
|
||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer)
|
||||
@ -22,11 +33,25 @@ module ActiveModel
|
||||
end
|
||||
|
||||
def test_includes_linked_comments
|
||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'comments')
|
||||
assert_equal([
|
||||
{id: "1", body: 'ZOMG A COMMENT'},
|
||||
{id: "2", body: 'ZOMG ANOTHER COMMENT'}
|
||||
], @adapter.serializable_hash[:linked][:comments])
|
||||
end
|
||||
|
||||
def test_no_include_linked_if_comments_is_empty
|
||||
serializer = PostSerializer.new(@post_without_comments)
|
||||
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
|
||||
|
||||
assert_nil adapter.serializable_hash[:linked]
|
||||
end
|
||||
|
||||
def test_include_type_for_association_when_is_different_than_name
|
||||
serializer = BlogSerializer.new(@blog)
|
||||
adapter = ActiveModel::Serializer::Adapter::JsonApi.new(serializer)
|
||||
assert_equal({type: "posts", ids: ["1"]}, adapter.serializable_hash[:blogs][:links][:articles])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
40
test/adapter/json_api/linked_test.rb
Normal file
40
test/adapter/json_api/linked_test.rb
Normal file
@ -0,0 +1,40 @@
|
||||
require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class Adapter
|
||||
class JsonApi
|
||||
class LinkedTest < Minitest::Test
|
||||
def setup
|
||||
@author = Author.new(id: 1, name: 'Steve K.')
|
||||
@first_post = Post.new(id: 1, title: 'Hello!!', body: 'Hello, world!!')
|
||||
@second_post = Post.new(id: 2, title: 'New Post', body: 'Body')
|
||||
@first_post.comments = []
|
||||
@second_post.comments = []
|
||||
@first_post.author = @author
|
||||
@second_post.author = @author
|
||||
@author.posts = [@first_post, @second_post]
|
||||
|
||||
@serializer = ArraySerializer.new([@first_post, @second_post])
|
||||
@adapter = ActiveModel::Serializer::Adapter::JsonApi.new(@serializer, include: 'author,comments')
|
||||
end
|
||||
|
||||
def test_include_multiple_posts_and_linked
|
||||
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
|
||||
@first_post.comments = [@first_comment, @second_comment]
|
||||
@first_comment.post = @first_post
|
||||
@first_comment.author = nil
|
||||
@second_comment.post = @first_post
|
||||
@second_comment.author = nil
|
||||
assert_equal([
|
||||
{ title: "Hello!!", body: "Hello, world!!", id: "1", links: { comments: ['1', '2'], author: "1" } },
|
||||
{ title: "New Post", body: "Body", id: "2", links: { comments: [], :author => "1" } }
|
||||
], @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])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -5,12 +5,14 @@ module ActiveModel
|
||||
class Adapter
|
||||
class JsonTest < Minitest::Test
|
||||
def setup
|
||||
@author = Author.new(id: 1, name: 'Steve K.')
|
||||
@post = Post.new(title: 'New Post', body: 'Body')
|
||||
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
|
||||
@post.comments = [@first_comment, @second_comment]
|
||||
@first_comment.post = @post
|
||||
@second_comment.post = @post
|
||||
@post.author = @author
|
||||
|
||||
@serializer = PostSerializer.new(@post)
|
||||
@adapter = ActiveModel::Serializer::Adapter::Json.new(@serializer)
|
||||
|
||||
10
test/fixtures/poro.rb
vendored
10
test/fixtures/poro.rb
vendored
@ -38,11 +38,13 @@ end
|
||||
Post = Class.new(Model)
|
||||
Comment = Class.new(Model)
|
||||
Author = Class.new(Model)
|
||||
Blog = Class.new(Model)
|
||||
|
||||
PostSerializer = Class.new(ActiveModel::Serializer) do
|
||||
attributes :title, :body, :id
|
||||
|
||||
has_many :comments
|
||||
belongs_to :author
|
||||
url :comments
|
||||
end
|
||||
|
||||
@ -50,6 +52,7 @@ CommentSerializer = Class.new(ActiveModel::Serializer) do
|
||||
attributes :id, :body
|
||||
|
||||
belongs_to :post
|
||||
belongs_to :author
|
||||
end
|
||||
|
||||
AuthorSerializer = Class.new(ActiveModel::Serializer) do
|
||||
@ -57,3 +60,10 @@ AuthorSerializer = Class.new(ActiveModel::Serializer) do
|
||||
|
||||
has_many :posts, embed: :ids
|
||||
end
|
||||
|
||||
BlogSerializer = Class.new(ActiveModel::Serializer) do
|
||||
attributes :id, :name
|
||||
|
||||
belongs_to :writer
|
||||
has_many :articles
|
||||
end
|
||||
|
||||
@ -2,7 +2,7 @@ require 'test_helper'
|
||||
|
||||
module ActiveModel
|
||||
class Serializer
|
||||
class AssocationsTest < Minitest::Test
|
||||
class AssociationsTest < Minitest::Test
|
||||
class Model
|
||||
def initialize(hash={})
|
||||
@attributes = hash
|
||||
@ -25,30 +25,40 @@ module ActiveModel
|
||||
|
||||
|
||||
def setup
|
||||
@author = Author.new(name: 'Steve K.')
|
||||
@post = Post.new({ title: 'New Post', body: 'Body' })
|
||||
@comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' })
|
||||
@post.comments = [@comment]
|
||||
@comment.post = @post
|
||||
@comment.author = nil
|
||||
@post.author = @author
|
||||
@author.posts = [@post]
|
||||
|
||||
@post_serializer = PostSerializer.new(@post)
|
||||
@author_serializer = AuthorSerializer.new(@author)
|
||||
@comment_serializer = CommentSerializer.new(@comment)
|
||||
end
|
||||
|
||||
def test_has_many
|
||||
assert_equal({comments: {type: :has_many, options: {}}}, @post_serializer.class._associations)
|
||||
@post_serializer.each_association do |name, serializer, options|
|
||||
assert_equal(:comments, name)
|
||||
assert_equal({}, options)
|
||||
assert_equal({posts: {type: :has_many, options: {embed: :ids}}}, @author_serializer.class._associations)
|
||||
@author_serializer.each_association do |name, serializer, options|
|
||||
assert_equal(:posts, name)
|
||||
assert_equal({embed: :ids}, options)
|
||||
assert_kind_of(ActiveModel::Serializer.config.array_serializer, serializer)
|
||||
end
|
||||
end
|
||||
|
||||
def test_has_one
|
||||
assert_equal({post: {type: :belongs_to, options: {}}}, @comment_serializer.class._associations)
|
||||
assert_equal({post: {type: :belongs_to, options: {}}, :author=>{:type=>:belongs_to, :options=>{}}}, @comment_serializer.class._associations)
|
||||
@comment_serializer.each_association do |name, serializer, options|
|
||||
assert_equal(:post, name)
|
||||
assert_equal({}, options)
|
||||
assert_kind_of(PostSerializer, serializer)
|
||||
if name == :post
|
||||
assert_equal({}, options)
|
||||
assert_kind_of(PostSerializer, serializer)
|
||||
elsif name == :author
|
||||
assert_equal({}, options)
|
||||
assert_nil serializer
|
||||
else
|
||||
flunk "Unknown association: #{name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user