active_model_serializers 0.10.0.rc2 → 0.10.0.rc3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +82 -0
- data/.rubocop_todo.yml +315 -0
- data/.simplecov +99 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +9 -3
- data/Gemfile +39 -8
- data/README.md +55 -31
- data/Rakefile +29 -2
- data/active_model_serializers.gemspec +37 -13
- data/appveyor.yml +25 -0
- data/docs/README.md +29 -0
- data/docs/general/adapters.md +110 -0
- data/docs/general/configuration_options.md +11 -0
- data/docs/general/getting_started.md +73 -0
- data/docs/howto/add_pagination_links.md +112 -0
- data/docs/howto/add_root_key.md +51 -0
- data/docs/howto/outside_controller_use.md +42 -0
- data/lib/action_controller/serialization.rb +24 -33
- data/lib/active_model/serializable_resource.rb +70 -0
- data/lib/active_model/serializer.rb +50 -131
- data/lib/active_model/serializer/adapter.rb +84 -21
- data/lib/active_model/serializer/adapter/flatten_json.rb +9 -9
- data/lib/active_model/serializer/adapter/fragment_cache.rb +10 -13
- data/lib/active_model/serializer/adapter/json.rb +25 -28
- data/lib/active_model/serializer/adapter/json/fragment_cache.rb +2 -12
- data/lib/active_model/serializer/adapter/json_api.rb +100 -98
- data/lib/active_model/serializer/adapter/json_api/fragment_cache.rb +4 -14
- data/lib/active_model/serializer/adapter/json_api/pagination_links.rb +50 -0
- data/lib/active_model/serializer/adapter/null.rb +2 -8
- data/lib/active_model/serializer/array_serializer.rb +22 -17
- data/lib/active_model/serializer/association.rb +20 -0
- data/lib/active_model/serializer/associations.rb +97 -0
- data/lib/active_model/serializer/belongs_to_reflection.rb +10 -0
- data/lib/active_model/serializer/collection_reflection.rb +7 -0
- data/lib/active_model/serializer/configuration.rb +1 -0
- data/lib/active_model/serializer/fieldset.rb +7 -7
- data/lib/active_model/serializer/has_many_reflection.rb +10 -0
- data/lib/active_model/serializer/has_one_reflection.rb +10 -0
- data/lib/active_model/serializer/lint.rb +129 -0
- data/lib/active_model/serializer/railtie.rb +7 -0
- data/lib/active_model/serializer/reflection.rb +74 -0
- data/lib/active_model/serializer/singular_reflection.rb +7 -0
- data/lib/active_model/serializer/utils.rb +35 -0
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model_serializers.rb +28 -14
- data/lib/generators/serializer/serializer_generator.rb +7 -7
- data/lib/generators/serializer/templates/{serializer.rb → serializer.rb.erb} +2 -2
- data/lib/tasks/rubocop.rake +0 -0
- data/test/action_controller/adapter_selector_test.rb +3 -3
- data/test/action_controller/explicit_serializer_test.rb +9 -9
- data/test/action_controller/json_api/linked_test.rb +179 -0
- data/test/action_controller/json_api/pagination_test.rb +116 -0
- data/test/action_controller/serialization_scope_name_test.rb +10 -6
- data/test/action_controller/serialization_test.rb +149 -112
- data/test/active_record_test.rb +9 -0
- data/test/adapter/fragment_cache_test.rb +11 -1
- data/test/adapter/json/belongs_to_test.rb +4 -5
- data/test/adapter/json/collection_test.rb +30 -21
- data/test/adapter/json/has_many_test.rb +20 -9
- data/test/adapter/json_api/belongs_to_test.rb +38 -38
- data/test/adapter/json_api/collection_test.rb +22 -23
- data/test/adapter/json_api/has_many_embed_ids_test.rb +2 -2
- data/test/adapter/json_api/has_many_explicit_serializer_test.rb +4 -4
- data/test/adapter/json_api/has_many_test.rb +54 -19
- data/test/adapter/json_api/has_one_test.rb +28 -8
- data/test/adapter/json_api/json_api_test.rb +37 -0
- data/test/adapter/json_api/linked_test.rb +75 -75
- data/test/adapter/json_api/pagination_links_test.rb +115 -0
- data/test/adapter/json_api/resource_type_config_test.rb +59 -0
- data/test/adapter/json_test.rb +18 -5
- data/test/adapter_test.rb +10 -11
- data/test/array_serializer_test.rb +63 -5
- data/test/capture_warnings.rb +65 -0
- data/test/fixtures/active_record.rb +56 -0
- data/test/fixtures/poro.rb +60 -29
- data/test/generators/scaffold_controller_generator_test.rb +1 -2
- data/test/generators/serializer_generator_test.rb +17 -12
- data/test/lint_test.rb +37 -0
- data/test/logger_test.rb +18 -0
- data/test/poro_test.rb +9 -0
- data/test/serializable_resource_test.rb +27 -0
- data/test/serializers/adapter_for_test.rb +123 -3
- data/test/serializers/association_macros_test.rb +36 -0
- data/test/serializers/associations_test.rb +70 -47
- data/test/serializers/attribute_test.rb +28 -4
- data/test/serializers/attributes_test.rb +8 -14
- data/test/serializers/cache_test.rb +58 -31
- data/test/serializers/fieldset_test.rb +3 -4
- data/test/serializers/meta_test.rb +42 -28
- data/test/serializers/root_test.rb +21 -0
- data/test/serializers/serializer_for_test.rb +1 -1
- data/test/support/rails_app.rb +21 -0
- data/test/support/serialization_testing.rb +13 -0
- data/test/support/simplecov.rb +6 -0
- data/test/support/stream_capture.rb +50 -0
- data/test/support/test_case.rb +5 -0
- data/test/test_helper.rb +41 -29
- data/test/utils/include_args_to_hash_test.rb +79 -0
- metadata +123 -17
- data/test/action_controller/json_api_linked_test.rb +0 -179
- data/test/action_controller/rescue_from_test.rb +0 -32
- data/test/serializers/urls_test.rb +0 -26
@@ -1,5 +1,12 @@
|
|
1
|
+
require 'rails/railtie'
|
1
2
|
module ActiveModel
|
2
3
|
class Railtie < Rails::Railtie
|
4
|
+
initializer 'active_model_serializers.logger' do
|
5
|
+
ActiveSupport.on_load(:action_controller) do
|
6
|
+
ActiveModelSerializers.logger = ActionController::Base.logger
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
3
10
|
initializer 'generators' do |app|
|
4
11
|
app.load_generators
|
5
12
|
require 'generators/serializer/resource_override'
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module ActiveModel
|
2
|
+
class Serializer
|
3
|
+
# Holds all the meta-data about an association as it was specified in the
|
4
|
+
# ActiveModel::Serializer class.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# class PostSerializer < ActiveModel::Serializer
|
8
|
+
# has_one :author, serializer: AuthorSerializer
|
9
|
+
# has_many :comments
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# PostSerializer._reflections #=>
|
13
|
+
# # [
|
14
|
+
# # HasOneReflection.new(:author, serializer: AuthorSerializer),
|
15
|
+
# # HasManyReflection.new(:comments)
|
16
|
+
# # ]
|
17
|
+
#
|
18
|
+
# So you can inspect reflections in your Adapters.
|
19
|
+
#
|
20
|
+
Reflection = Struct.new(:name, :options) do
|
21
|
+
# Build association. This method is used internally to
|
22
|
+
# build serializer's association by its reflection.
|
23
|
+
#
|
24
|
+
# @param [Serializer] subject is a parent serializer for given association
|
25
|
+
# @param [Hash{Symbol => Object}] parent_serializer_options
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
# # Given the following serializer defined:
|
29
|
+
# class PostSerializer < ActiveModel::Serializer
|
30
|
+
# has_many :comments, serializer: CommentSummarySerializer
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# # Then you instantiate your serializer
|
34
|
+
# post_serializer = PostSerializer.new(post, foo: 'bar') #
|
35
|
+
# # to build association for comments you need to get reflection
|
36
|
+
# comments_reflection = PostSerializer._reflections.detect { |r| r.name == :comments }
|
37
|
+
# # and #build_association
|
38
|
+
# comments_reflection.build_association(post_serializer, foo: 'bar')
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
#
|
42
|
+
def build_association(subject, parent_serializer_options)
|
43
|
+
association_value = subject.send(name)
|
44
|
+
reflection_options = options.dup
|
45
|
+
serializer_class = ActiveModel::Serializer.serializer_for(association_value, reflection_options)
|
46
|
+
|
47
|
+
if serializer_class
|
48
|
+
begin
|
49
|
+
serializer = serializer_class.new(
|
50
|
+
association_value,
|
51
|
+
serializer_options(parent_serializer_options, reflection_options)
|
52
|
+
)
|
53
|
+
rescue ActiveModel::Serializer::ArraySerializer::NoSerializerError
|
54
|
+
reflection_options[:virtual_value] = association_value.try(:as_json) || association_value
|
55
|
+
end
|
56
|
+
elsif !association_value.nil? && !association_value.instance_of?(Object)
|
57
|
+
reflection_options[:virtual_value] = association_value
|
58
|
+
end
|
59
|
+
|
60
|
+
Association.new(name, serializer, reflection_options)
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def serializer_options(parent_serializer_options, reflection_options)
|
66
|
+
serializer = reflection_options.fetch(:serializer, nil)
|
67
|
+
|
68
|
+
serializer_options = parent_serializer_options.except(:serializer)
|
69
|
+
serializer_options[:serializer] = serializer if serializer
|
70
|
+
serializer_options
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ActiveModel::Serializer::Utils
|
2
|
+
module_function
|
3
|
+
|
4
|
+
# Translates a comma separated list of dot separated paths (JSONAPI format) into a Hash.
|
5
|
+
# Example: `'posts.author, posts.comments.upvotes, posts.comments.author'` would become `{ posts: { author: {}, comments: { author: {}, upvotes: {} } } }`.
|
6
|
+
#
|
7
|
+
# @param [String] included
|
8
|
+
# @return [Hash] a Hash representing the same tree structure
|
9
|
+
def include_string_to_hash(included)
|
10
|
+
included.delete(' ').split(',').inject({}) do |hash, path|
|
11
|
+
hash.deep_merge!(path.split('.').reverse_each.inject({}) { |a, e| { e.to_sym => a } })
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Translates the arguments passed to the include option into a Hash. The format can be either
|
16
|
+
# a String (see #include_string_to_hash), an Array of Symbols and Hashes, or a mix of both.
|
17
|
+
# Example: `posts: [:author, comments: [:author, :upvotes]]` would become `{ posts: { author: {}, comments: { author: {}, upvotes: {} } } }`.
|
18
|
+
#
|
19
|
+
# @param [Symbol, Hash, Array, String] included
|
20
|
+
# @return [Hash] a Hash representing the same tree structure
|
21
|
+
def include_args_to_hash(included)
|
22
|
+
case included
|
23
|
+
when Symbol
|
24
|
+
{ included => {} }
|
25
|
+
when Hash
|
26
|
+
included.each_with_object({}) { |(key, value), hash| hash[key] = include_args_to_hash(value) }
|
27
|
+
when Array
|
28
|
+
included.inject({}) { |a, e| a.merge!(include_args_to_hash(e)) }
|
29
|
+
when String
|
30
|
+
include_string_to_hash(included)
|
31
|
+
else
|
32
|
+
{}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,19 +1,33 @@
|
|
1
|
+
require 'logger'
|
1
2
|
require 'active_model'
|
2
|
-
require '
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
|
3
|
+
require 'active_support/railtie'
|
4
|
+
require 'action_controller'
|
5
|
+
require 'action_controller/railtie'
|
6
|
+
module ActiveModelSerializers
|
7
|
+
mattr_accessor :logger
|
8
|
+
self.logger = Rails.logger || Logger.new(IO::NULL)
|
6
9
|
|
7
|
-
|
8
|
-
require 'action_controller'
|
9
|
-
require 'action_controller/serialization'
|
10
|
+
module_function
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
def silence_warnings
|
13
|
+
verbose = $VERBOSE
|
14
|
+
$VERBOSE = nil
|
15
|
+
yield
|
16
|
+
ensure
|
17
|
+
$VERBOSE = verbose
|
16
18
|
end
|
17
|
-
rescue LoadError
|
18
|
-
# rails not installed, continuing
|
19
19
|
end
|
20
|
+
|
21
|
+
require 'active_model/serializer'
|
22
|
+
require 'active_model/serializable_resource'
|
23
|
+
require 'active_model/serializer/version'
|
24
|
+
|
25
|
+
require 'action_controller/serialization'
|
26
|
+
ActiveSupport.on_load(:action_controller) do
|
27
|
+
include ::ActionController::Serialization
|
28
|
+
ActionDispatch::Reloader.to_prepare do
|
29
|
+
ActiveModel::Serializer.serializers_cache.clear
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
require 'active_model/serializer/railtie'
|
@@ -1,15 +1,15 @@
|
|
1
1
|
module Rails
|
2
2
|
module Generators
|
3
3
|
class SerializerGenerator < NamedBase
|
4
|
-
source_root File.expand_path(
|
5
|
-
check_class_collision :suffix =>
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
check_class_collision :suffix => 'Serializer'
|
6
6
|
|
7
|
-
argument :attributes, :type => :array, :default => [], :banner =>
|
7
|
+
argument :attributes, :type => :array, :default => [], :banner => 'field:type field:type'
|
8
8
|
|
9
|
-
class_option :parent, :type => :string, :desc =>
|
9
|
+
class_option :parent, :type => :string, :desc => 'The parent class for the generated serializer'
|
10
10
|
|
11
11
|
def create_serializer_file
|
12
|
-
template 'serializer.rb', File.join('app/serializers', class_path, "#{file_name}_serializer.rb")
|
12
|
+
template 'serializer.rb.erb', File.join('app/serializers', class_path, "#{file_name}_serializer.rb")
|
13
13
|
end
|
14
14
|
|
15
15
|
private
|
@@ -26,9 +26,9 @@ module Rails
|
|
26
26
|
if options[:parent]
|
27
27
|
options[:parent]
|
28
28
|
elsif defined?(::ApplicationSerializer)
|
29
|
-
|
29
|
+
'ApplicationSerializer'
|
30
30
|
else
|
31
|
-
|
31
|
+
'ActiveModel::Serializer'
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
<% module_namespacing do -%>
|
2
2
|
class <%= class_name %>Serializer < <%= parent_class_name %>
|
3
3
|
attributes <%= attributes_names.map(&:inspect).join(", ") %>
|
4
|
-
end
|
5
4
|
<% association_names.each do |attribute| -%>
|
6
|
-
|
5
|
+
has_one :<%= attribute %>
|
7
6
|
<% end -%>
|
7
|
+
end
|
8
8
|
<% end -%>
|
File without changes
|
@@ -33,10 +33,10 @@ module ActionController
|
|
33
33
|
expected = {
|
34
34
|
data: {
|
35
35
|
id: assigns(:profile).id.to_s,
|
36
|
-
type:
|
36
|
+
type: 'profiles',
|
37
37
|
attributes: {
|
38
|
-
name:
|
39
|
-
description:
|
38
|
+
name: 'Name 1',
|
39
|
+
description: 'Description 1',
|
40
40
|
}
|
41
41
|
}
|
42
42
|
}
|
@@ -100,11 +100,11 @@ module ActionController
|
|
100
100
|
get :render_array_using_explicit_serializer_and_custom_serializers
|
101
101
|
|
102
102
|
expected = [
|
103
|
-
{
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
103
|
+
{ 'title' => 'New Post',
|
104
|
+
'body' => 'Body',
|
105
|
+
'id' => assigns(:post).id,
|
106
|
+
'comments' => [{ 'id' => 1 }, { 'id' => 2 }],
|
107
|
+
'author' => { 'id' => assigns(:author).id }
|
108
108
|
}
|
109
109
|
]
|
110
110
|
|
@@ -116,13 +116,13 @@ module ActionController
|
|
116
116
|
|
117
117
|
expected = {
|
118
118
|
id: 1337,
|
119
|
-
name:
|
119
|
+
name: 'Amazing Place',
|
120
120
|
locations: [
|
121
121
|
{
|
122
122
|
id: 42,
|
123
|
-
lat:
|
124
|
-
lng:
|
125
|
-
place:
|
123
|
+
lat: '-23.550520',
|
124
|
+
lng: '-46.633309',
|
125
|
+
place: 'Nowhere' # is a virtual attribute on LocationSerializer
|
126
126
|
}
|
127
127
|
]
|
128
128
|
}
|
@@ -0,0 +1,179 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
module Serialization
|
5
|
+
class JsonApi
|
6
|
+
class LinkedTest < ActionController::TestCase
|
7
|
+
class LinkedTestController < ActionController::Base
|
8
|
+
def setup_post
|
9
|
+
ActionController::Base.cache_store.clear
|
10
|
+
@role1 = Role.new(id: 1, name: 'admin')
|
11
|
+
@role2 = Role.new(id: 2, name: 'colab')
|
12
|
+
@author = Author.new(id: 1, name: 'Steve K.')
|
13
|
+
@author.posts = []
|
14
|
+
@author.bio = nil
|
15
|
+
@author.roles = [@role1, @role2]
|
16
|
+
@role1.author = @author
|
17
|
+
@role2.author = @author
|
18
|
+
@author2 = Author.new(id: 2, name: 'Anonymous')
|
19
|
+
@author2.posts = []
|
20
|
+
@author2.bio = nil
|
21
|
+
@author2.roles = []
|
22
|
+
@post = Post.new(id: 1, title: 'New Post', body: 'Body')
|
23
|
+
@first_comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
24
|
+
@second_comment = Comment.new(id: 2, body: 'ZOMG ANOTHER COMMENT')
|
25
|
+
@post.comments = [@first_comment, @second_comment]
|
26
|
+
@post.author = @author
|
27
|
+
@first_comment.post = @post
|
28
|
+
@first_comment.author = @author2
|
29
|
+
@second_comment.post = @post
|
30
|
+
@second_comment.author = nil
|
31
|
+
@post2 = Post.new(id: 2, title: 'Another Post', body: 'Body')
|
32
|
+
@post2.author = @author
|
33
|
+
@post2.comments = []
|
34
|
+
@blog = Blog.new(id: 1, name: 'My Blog!!')
|
35
|
+
@post.blog = @blog
|
36
|
+
@post2.blog = @blog
|
37
|
+
end
|
38
|
+
|
39
|
+
def render_resource_without_include
|
40
|
+
setup_post
|
41
|
+
render json: @post, adapter: :json_api
|
42
|
+
end
|
43
|
+
|
44
|
+
def render_resource_with_include
|
45
|
+
setup_post
|
46
|
+
render json: @post, include: [:author], adapter: :json_api
|
47
|
+
end
|
48
|
+
|
49
|
+
def render_resource_with_nested_include
|
50
|
+
setup_post
|
51
|
+
render json: @post, include: [comments: [:author]], adapter: :json_api
|
52
|
+
end
|
53
|
+
|
54
|
+
def render_resource_with_nested_has_many_include
|
55
|
+
setup_post
|
56
|
+
render json: @post, include: 'author.roles', adapter: :json_api
|
57
|
+
end
|
58
|
+
|
59
|
+
def render_resource_with_missing_nested_has_many_include
|
60
|
+
setup_post
|
61
|
+
@post.author = @author2 # author2 has no roles.
|
62
|
+
render json: @post, include: [author: [:roles]], adapter: :json_api
|
63
|
+
end
|
64
|
+
|
65
|
+
def render_collection_with_missing_nested_has_many_include
|
66
|
+
setup_post
|
67
|
+
@post.author = @author2
|
68
|
+
render json: [@post, @post2], include: [author: [:roles]], adapter: :json_api
|
69
|
+
end
|
70
|
+
|
71
|
+
def render_collection_without_include
|
72
|
+
setup_post
|
73
|
+
render json: [@post], adapter: :json_api
|
74
|
+
end
|
75
|
+
|
76
|
+
def render_collection_with_include
|
77
|
+
setup_post
|
78
|
+
render json: [@post], include: 'author, comments', adapter: :json_api
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
tests LinkedTestController
|
83
|
+
|
84
|
+
def test_render_resource_without_include
|
85
|
+
get :render_resource_without_include
|
86
|
+
response = JSON.parse(@response.body)
|
87
|
+
refute response.key? 'included'
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_render_resource_with_include
|
91
|
+
get :render_resource_with_include
|
92
|
+
response = JSON.parse(@response.body)
|
93
|
+
assert response.key? 'included'
|
94
|
+
assert_equal 1, response['included'].size
|
95
|
+
assert_equal 'Steve K.', response['included'].first['attributes']['name']
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_render_resource_with_nested_has_many_include
|
99
|
+
get :render_resource_with_nested_has_many_include
|
100
|
+
response = JSON.parse(@response.body)
|
101
|
+
expected_linked = [
|
102
|
+
{
|
103
|
+
'id' => '1',
|
104
|
+
'type' => 'authors',
|
105
|
+
'attributes' => {
|
106
|
+
'name' => 'Steve K.'
|
107
|
+
},
|
108
|
+
'relationships' => {
|
109
|
+
'posts' => { 'data' => [] },
|
110
|
+
'roles' => { 'data' => [{ 'type' => 'roles', 'id' => '1' }, { 'type' => 'roles', 'id' => '2' }] },
|
111
|
+
'bio' => { 'data' => nil }
|
112
|
+
}
|
113
|
+
}, {
|
114
|
+
'id' => '1',
|
115
|
+
'type' => 'roles',
|
116
|
+
'attributes' => {
|
117
|
+
'name' => 'admin',
|
118
|
+
'description' => nil,
|
119
|
+
'slug' => 'admin-1'
|
120
|
+
},
|
121
|
+
'relationships' => {
|
122
|
+
'author' => { 'data' => { 'type' => 'authors', 'id' => '1' } }
|
123
|
+
}
|
124
|
+
}, {
|
125
|
+
'id' => '2',
|
126
|
+
'type' => 'roles',
|
127
|
+
'attributes' => {
|
128
|
+
'name' => 'colab',
|
129
|
+
'description' => nil,
|
130
|
+
'slug' => 'colab-2'
|
131
|
+
},
|
132
|
+
'relationships' => {
|
133
|
+
'author' => { 'data' => { 'type' => 'authors', 'id' => '1' } }
|
134
|
+
}
|
135
|
+
}
|
136
|
+
]
|
137
|
+
assert_equal expected_linked, response['included']
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_render_resource_with_nested_include
|
141
|
+
get :render_resource_with_nested_include
|
142
|
+
response = JSON.parse(@response.body)
|
143
|
+
assert response.key? 'included'
|
144
|
+
assert_equal 3, response['included'].size
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_render_collection_without_include
|
148
|
+
get :render_collection_without_include
|
149
|
+
response = JSON.parse(@response.body)
|
150
|
+
refute response.key? 'included'
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_render_collection_with_include
|
154
|
+
get :render_collection_with_include
|
155
|
+
response = JSON.parse(@response.body)
|
156
|
+
assert response.key? 'included'
|
157
|
+
end
|
158
|
+
|
159
|
+
def test_render_resource_with_nested_attributes_even_when_missing_associations
|
160
|
+
get :render_resource_with_missing_nested_has_many_include
|
161
|
+
response = JSON.parse(@response.body)
|
162
|
+
assert response.key? 'included'
|
163
|
+
refute has_type?(response['included'], 'roles')
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_render_collection_with_missing_nested_has_many_include
|
167
|
+
get :render_collection_with_missing_nested_has_many_include
|
168
|
+
response = JSON.parse(@response.body)
|
169
|
+
assert response.key? 'included'
|
170
|
+
assert has_type?(response['included'], 'roles')
|
171
|
+
end
|
172
|
+
|
173
|
+
def has_type?(collection, value)
|
174
|
+
collection.detect { |i| i['type'] == value }
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|