active_model_serializers 0.10.4 → 0.10.5
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/.travis.yml +7 -3
- data/CHANGELOG.md +25 -1
- data/README.md +4 -4
- data/active_model_serializers.gemspec +1 -1
- data/appveyor.yml +9 -3
- data/docs/general/logging.md +7 -0
- data/docs/general/serializers.md +3 -3
- data/docs/howto/add_pagination_links.md +13 -13
- data/docs/howto/add_relationship_links.md +24 -21
- data/docs/howto/outside_controller_use.md +3 -2
- data/docs/howto/serialize_poro.md +46 -5
- data/docs/howto/upgrade_from_0_8_to_0_10.md +1 -1
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model_serializers.rb +8 -0
- data/lib/active_model_serializers/model.rb +108 -30
- data/lib/active_model_serializers/test/schema.rb +2 -2
- data/lib/generators/rails/resource_override.rb +1 -1
- data/test/action_controller/adapter_selector_test.rb +11 -2
- data/test/action_controller/json_api/fields_test.rb +15 -6
- data/test/action_controller/json_api/transform_test.rb +11 -3
- data/test/action_controller/namespace_lookup_test.rb +14 -8
- data/test/action_controller/serialization_scope_name_test.rb +12 -6
- data/test/action_controller/serialization_test.rb +1 -1
- data/test/active_model_serializers/model_test.rb +122 -2
- data/test/active_model_serializers/railtie_test_isolated.rb +12 -7
- data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +37 -19
- data/test/adapter/attributes_test.rb +2 -5
- data/test/adapter/json/has_many_test.rb +10 -2
- data/test/adapter/json_api/fields_test.rb +11 -3
- data/test/adapter/json_api/has_many_test.rb +10 -2
- data/test/adapter/json_api/include_data_if_sideloaded_test.rb +22 -5
- data/test/adapter/json_api/linked_test.rb +3 -3
- data/test/adapter/json_api/links_test.rb +1 -1
- data/test/adapter/json_api/relationship_test.rb +1 -1
- data/test/adapter/json_api/transform_test.rb +11 -3
- data/test/cache_test.rb +100 -28
- data/test/collection_serializer_test.rb +23 -10
- data/test/fixtures/active_record.rb +45 -10
- data/test/fixtures/poro.rb +115 -176
- data/test/generators/serializer_generator_test.rb +1 -0
- data/test/grape_test.rb +20 -2
- data/test/serializers/associations_test.rb +28 -7
- data/test/serializers/attribute_test.rb +4 -2
- data/test/serializers/caching_configuration_test_isolated.rb +6 -6
- data/test/serializers/options_test.rb +17 -6
- data/test/serializers/read_attribute_for_serialization_test.rb +3 -3
- data/test/serializers/serialization_test.rb +2 -2
- data/test/serializers/serializer_for_test.rb +6 -6
- data/test/serializers/serializer_for_with_namespace_test.rb +6 -5
- data/test/support/rails_app.rb +2 -0
- data/test/test_helper.rb +12 -0
- metadata +13 -7
@@ -4,11 +4,13 @@ require 'support/isolated_unit'
|
|
4
4
|
class RailtieTest < ActiveSupport::TestCase
|
5
5
|
include ActiveSupport::Testing::Isolation
|
6
6
|
|
7
|
-
class
|
7
|
+
class WithRailsRequiredFirst < RailtieTest
|
8
8
|
setup do
|
9
9
|
require 'rails'
|
10
10
|
require 'active_model_serializers'
|
11
|
-
make_basic_app
|
11
|
+
make_basic_app do |app|
|
12
|
+
app.config.action_controller.perform_caching = true
|
13
|
+
end
|
12
14
|
end
|
13
15
|
|
14
16
|
test 'mixes ActionController::Serialization into ActionController::Base' do
|
@@ -32,14 +34,17 @@ class RailtieTest < ActiveSupport::TestCase
|
|
32
34
|
|
33
35
|
test 'it is configured for caching' do
|
34
36
|
assert_equal ActionController::Base.cache_store, ActiveModelSerializers.config.cache_store
|
35
|
-
assert_equal Rails.configuration.action_controller.perform_caching
|
37
|
+
assert_equal true, Rails.configuration.action_controller.perform_caching
|
38
|
+
assert_equal true, ActiveModelSerializers.config.perform_caching
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
39
|
-
class
|
42
|
+
class WithoutRailsRequiredFirst < RailtieTest
|
40
43
|
setup do
|
41
44
|
require 'active_model_serializers'
|
42
|
-
make_basic_app
|
45
|
+
make_basic_app do |app|
|
46
|
+
app.config.action_controller.perform_caching = true
|
47
|
+
end
|
43
48
|
end
|
44
49
|
|
45
50
|
test 'does not mix ActionController::Serialization into ActionController::Base' do
|
@@ -56,8 +61,8 @@ class RailtieTest < ActiveSupport::TestCase
|
|
56
61
|
test 'it is not configured for caching' do
|
57
62
|
refute_nil ActionController::Base.cache_store
|
58
63
|
assert_nil ActiveModelSerializers.config.cache_store
|
59
|
-
|
60
|
-
|
64
|
+
assert_equal true, Rails.configuration.action_controller.perform_caching
|
65
|
+
assert_nil ActiveModelSerializers.config.perform_caching
|
61
66
|
end
|
62
67
|
end
|
63
68
|
end
|
@@ -12,7 +12,17 @@ class JsonApiRendererTest < ActionDispatch::IntegrationTest
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def render_with_jsonapi_renderer
|
15
|
-
|
15
|
+
permitted_params = params.permit(data: [:id, :type, attributes: [:name]])
|
16
|
+
permitted_params = permitted_params.to_h.with_indifferent_access
|
17
|
+
attributes =
|
18
|
+
if permitted_params[:data]
|
19
|
+
permitted_params[:data][:attributes].merge(id: permitted_params[:data][:id])
|
20
|
+
else
|
21
|
+
# Rails returns empty params when no mime type can be negotiated.
|
22
|
+
# (Until https://github.com/rails/rails/pull/26632 is reviewed.)
|
23
|
+
permitted_params
|
24
|
+
end
|
25
|
+
author = Author.new(attributes)
|
16
26
|
render jsonapi: author
|
17
27
|
end
|
18
28
|
|
@@ -32,6 +42,17 @@ class JsonApiRendererTest < ActionDispatch::IntegrationTest
|
|
32
42
|
assert_equal(expected, TestController.last_request_parameters)
|
33
43
|
end
|
34
44
|
|
45
|
+
def define_author_model_and_serializer
|
46
|
+
TestController.const_set(:Author, Class.new(ActiveModelSerializers::Model) do
|
47
|
+
attributes :id, :name
|
48
|
+
end)
|
49
|
+
TestController.const_set(:AuthorSerializer, Class.new(ActiveModel::Serializer) do
|
50
|
+
type 'users'
|
51
|
+
attribute :id
|
52
|
+
attribute :name
|
53
|
+
end)
|
54
|
+
end
|
55
|
+
|
35
56
|
class WithoutRenderer < JsonApiRendererTest
|
36
57
|
setup do
|
37
58
|
require 'rails'
|
@@ -47,6 +68,7 @@ class JsonApiRendererTest < ActionDispatch::IntegrationTest
|
|
47
68
|
match ':action', to: TestController, via: [:get, :post]
|
48
69
|
end
|
49
70
|
end
|
71
|
+
define_author_model_and_serializer
|
50
72
|
end
|
51
73
|
|
52
74
|
def test_jsonapi_parser_not_registered
|
@@ -59,18 +81,12 @@ class JsonApiRendererTest < ActionDispatch::IntegrationTest
|
|
59
81
|
end
|
60
82
|
|
61
83
|
def test_jsonapi_renderer_not_registered
|
62
|
-
|
63
|
-
'data' => {
|
64
|
-
'attributes' => {
|
65
|
-
'name' => 'Johnny Rico'
|
66
|
-
},
|
67
|
-
'type' => 'users'
|
68
|
-
}
|
69
|
-
}
|
70
|
-
payload = '{"data": {"attributes": {"name": "Johnny Rico"}, "type": "authors"}}'
|
84
|
+
payload = '{"data": {"attributes": {"name": "Johnny Rico"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}'
|
71
85
|
headers = { 'CONTENT_TYPE' => 'application/vnd.api+json' }
|
72
86
|
post '/render_with_jsonapi_renderer', params: payload, headers: headers
|
73
|
-
|
87
|
+
assert_equal '', response.body
|
88
|
+
assert_equal 500, response.status
|
89
|
+
assert_equal ActionView::MissingTemplate, request.env['action_dispatch.exception'].class
|
74
90
|
end
|
75
91
|
|
76
92
|
def test_jsonapi_parser
|
@@ -98,6 +114,7 @@ class JsonApiRendererTest < ActionDispatch::IntegrationTest
|
|
98
114
|
match ':action', to: TestController, via: [:get, :post]
|
99
115
|
end
|
100
116
|
end
|
117
|
+
define_author_model_and_serializer
|
101
118
|
end
|
102
119
|
|
103
120
|
def test_jsonapi_parser_registered
|
@@ -113,16 +130,16 @@ class JsonApiRendererTest < ActionDispatch::IntegrationTest
|
|
113
130
|
def test_jsonapi_renderer_registered
|
114
131
|
expected = {
|
115
132
|
'data' => {
|
116
|
-
'
|
117
|
-
|
118
|
-
}
|
119
|
-
'type' => 'users'
|
133
|
+
'id' => '36c9c04e-86b1-4636-a5b0-8616672d1765',
|
134
|
+
'type' => 'users',
|
135
|
+
'attributes' => { 'name' => 'Johnny Rico' }
|
120
136
|
}
|
121
137
|
}
|
122
|
-
|
138
|
+
|
139
|
+
payload = '{"data": {"attributes": {"name": "Johnny Rico"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}'
|
123
140
|
headers = { 'CONTENT_TYPE' => 'application/vnd.api+json' }
|
124
141
|
post '/render_with_jsonapi_renderer', params: payload, headers: headers
|
125
|
-
|
142
|
+
assert_equal expected.to_json, response.body
|
126
143
|
end
|
127
144
|
|
128
145
|
def test_jsonapi_parser
|
@@ -132,10 +149,11 @@ class JsonApiRendererTest < ActionDispatch::IntegrationTest
|
|
132
149
|
'attributes' => {
|
133
150
|
'name' => 'John Doe'
|
134
151
|
},
|
135
|
-
'type' => 'users'
|
152
|
+
'type' => 'users',
|
153
|
+
'id' => '36c9c04e-86b1-4636-a5b0-8616672d1765'
|
136
154
|
}
|
137
155
|
},
|
138
|
-
'{"data": {"attributes": {"name": "John Doe"}, "type": "users"}}',
|
156
|
+
'{"data": {"attributes": {"name": "John Doe"}, "type": "users", "id": "36c9c04e-86b1-4636-a5b0-8616672d1765"}}',
|
139
157
|
'CONTENT_TYPE' => 'application/vnd.api+json'
|
140
158
|
)
|
141
159
|
end
|
@@ -3,11 +3,8 @@ require 'test_helper'
|
|
3
3
|
module ActiveModelSerializers
|
4
4
|
module Adapter
|
5
5
|
class AttributesTest < ActiveSupport::TestCase
|
6
|
-
class Person
|
7
|
-
|
8
|
-
include ActiveModel::Serialization
|
9
|
-
|
10
|
-
attr_accessor :first_name, :last_name
|
6
|
+
class Person < ActiveModelSerializers::Model
|
7
|
+
attributes :first_name, :last_name
|
11
8
|
end
|
12
9
|
|
13
10
|
class PersonSerializer < ActiveModel::Serializer
|
@@ -4,6 +4,10 @@ module ActiveModelSerializers
|
|
4
4
|
module Adapter
|
5
5
|
class Json
|
6
6
|
class HasManyTestTest < ActiveSupport::TestCase
|
7
|
+
class ModelWithoutSerializer < ::Model
|
8
|
+
attributes :id, :name
|
9
|
+
end
|
10
|
+
|
7
11
|
def setup
|
8
12
|
ActionController::Base.cache_store.clear
|
9
13
|
@author = Author.new(id: 1, name: 'Steve K.')
|
@@ -16,7 +20,7 @@ module ActiveModelSerializers
|
|
16
20
|
@second_comment.post = @post
|
17
21
|
@blog = Blog.new(id: 1, name: 'My Blog!!')
|
18
22
|
@post.blog = @blog
|
19
|
-
@tag =
|
23
|
+
@tag = ModelWithoutSerializer.new(id: 1, name: '#hash_tag')
|
20
24
|
@post.tags = [@tag]
|
21
25
|
end
|
22
26
|
|
@@ -30,7 +34,11 @@ module ActiveModelSerializers
|
|
30
34
|
end
|
31
35
|
|
32
36
|
def test_has_many_with_no_serializer
|
33
|
-
|
37
|
+
post_serializer_class = Class.new(ActiveModel::Serializer) do
|
38
|
+
attributes :id
|
39
|
+
has_many :tags
|
40
|
+
end
|
41
|
+
serializer = post_serializer_class.new(@post)
|
34
42
|
adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
|
35
43
|
assert_equal({
|
36
44
|
id: 42,
|
@@ -4,9 +4,17 @@ module ActiveModelSerializers
|
|
4
4
|
module Adapter
|
5
5
|
class JsonApi
|
6
6
|
class FieldsTest < ActiveSupport::TestCase
|
7
|
-
class Post < ::Model
|
8
|
-
|
9
|
-
|
7
|
+
class Post < ::Model
|
8
|
+
attributes :title, :body
|
9
|
+
associations :author, :comments
|
10
|
+
end
|
11
|
+
class Author < ::Model
|
12
|
+
attributes :name, :birthday
|
13
|
+
end
|
14
|
+
class Comment < ::Model
|
15
|
+
attributes :body
|
16
|
+
associations :author, :post
|
17
|
+
end
|
10
18
|
|
11
19
|
class PostSerializer < ActiveModel::Serializer
|
12
20
|
type 'posts'
|
@@ -4,6 +4,10 @@ module ActiveModelSerializers
|
|
4
4
|
module Adapter
|
5
5
|
class JsonApi
|
6
6
|
class HasManyTest < ActiveSupport::TestCase
|
7
|
+
class ModelWithoutSerializer < ::Model
|
8
|
+
attributes :id, :name
|
9
|
+
end
|
10
|
+
|
7
11
|
def setup
|
8
12
|
ActionController::Base.cache_store.clear
|
9
13
|
@author = Author.new(id: 1, name: 'Steve K.')
|
@@ -26,7 +30,7 @@ module ActiveModelSerializers
|
|
26
30
|
@blog.articles = [@post]
|
27
31
|
@post.blog = @blog
|
28
32
|
@post_without_comments.blog = nil
|
29
|
-
@tag =
|
33
|
+
@tag = ModelWithoutSerializer.new(id: 1, name: '#hash_tag')
|
30
34
|
@post.tags = [@tag]
|
31
35
|
@serializer = PostSerializer.new(@post)
|
32
36
|
@adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer)
|
@@ -129,7 +133,11 @@ module ActiveModelSerializers
|
|
129
133
|
end
|
130
134
|
|
131
135
|
def test_has_many_with_no_serializer
|
132
|
-
|
136
|
+
post_serializer_class = Class.new(ActiveModel::Serializer) do
|
137
|
+
attributes :id
|
138
|
+
has_many :tags
|
139
|
+
end
|
140
|
+
serializer = post_serializer_class.new(@post)
|
133
141
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
134
142
|
|
135
143
|
assert_equal({
|
@@ -5,18 +5,30 @@ module ActiveModel
|
|
5
5
|
module Adapter
|
6
6
|
class JsonApi
|
7
7
|
class IncludeParamTest < ActiveSupport::TestCase
|
8
|
-
IncludeParamAuthor = Class.new(::Model)
|
8
|
+
IncludeParamAuthor = Class.new(::Model) do
|
9
|
+
associations :tags, :posts
|
10
|
+
end
|
9
11
|
|
10
12
|
class CustomCommentLoader
|
11
13
|
def all
|
12
14
|
[{ foo: 'bar' }]
|
13
15
|
end
|
14
16
|
end
|
17
|
+
class Tag < ::Model
|
18
|
+
attributes :id, :name
|
19
|
+
end
|
15
20
|
|
16
21
|
class TagSerializer < ActiveModel::Serializer
|
22
|
+
type 'tags'
|
17
23
|
attributes :id, :name
|
18
24
|
end
|
19
25
|
|
26
|
+
class PostWithTagsSerializer < ActiveModel::Serializer
|
27
|
+
type 'posts'
|
28
|
+
attributes :id
|
29
|
+
has_many :tags
|
30
|
+
end
|
31
|
+
|
20
32
|
class IncludeParamAuthorSerializer < ActiveModel::Serializer
|
21
33
|
class_attribute :comment_loader
|
22
34
|
|
@@ -144,20 +156,25 @@ module ActiveModel
|
|
144
156
|
end
|
145
157
|
|
146
158
|
def test_node_not_included_when_no_link
|
147
|
-
expected =
|
148
|
-
assert_relationship(:unlinked_tags, expected)
|
159
|
+
expected = { meta: {} }
|
160
|
+
assert_relationship(:unlinked_tags, expected, key_transform: :unaltered)
|
149
161
|
end
|
150
162
|
|
151
163
|
private
|
152
164
|
|
165
|
+
def assert_relationship(relationship_name, expected, opts = {})
|
166
|
+
actual = relationship_data(relationship_name, opts)
|
167
|
+
assert_equal(expected, actual)
|
168
|
+
end
|
169
|
+
|
153
170
|
def result(opts)
|
154
171
|
opts = { adapter: :json_api }.merge(opts)
|
155
172
|
serializable(@author, opts).serializable_hash
|
156
173
|
end
|
157
174
|
|
158
|
-
def
|
175
|
+
def relationship_data(relationship_name, opts = {})
|
159
176
|
hash = result(opts)
|
160
|
-
|
177
|
+
hash[:data][:relationships][relationship_name]
|
161
178
|
end
|
162
179
|
end
|
163
180
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class NestedPost < ::Model; end
|
3
|
+
class NestedPost < ::Model; associations :nested_posts end
|
4
4
|
class NestedPostSerializer < ActiveModel::Serializer
|
5
5
|
has_many :nested_posts
|
6
6
|
end
|
@@ -301,8 +301,8 @@ module ActiveModelSerializers
|
|
301
301
|
end
|
302
302
|
|
303
303
|
class NoDuplicatesTest < ActiveSupport::TestCase
|
304
|
-
class Post < ::Model; end
|
305
|
-
class Author < ::Model; end
|
304
|
+
class Post < ::Model; associations :author end
|
305
|
+
class Author < ::Model; associations :posts, :roles, :bio end
|
306
306
|
|
307
307
|
class PostSerializer < ActiveModel::Serializer
|
308
308
|
type 'posts'
|
@@ -4,7 +4,7 @@ module ActiveModelSerializers
|
|
4
4
|
module Adapter
|
5
5
|
class JsonApi
|
6
6
|
class LinksTest < ActiveSupport::TestCase
|
7
|
-
class LinkAuthor < ::Model; end
|
7
|
+
class LinkAuthor < ::Model; associations :posts end
|
8
8
|
class LinkAuthorSerializer < ActiveModel::Serializer
|
9
9
|
link :self do
|
10
10
|
href "http://example.com/link_author/#{object.id}"
|
@@ -4,9 +4,17 @@ module ActiveModelSerializers
|
|
4
4
|
module Adapter
|
5
5
|
class JsonApi
|
6
6
|
class KeyCaseTest < ActiveSupport::TestCase
|
7
|
-
class Post < ::Model
|
8
|
-
|
9
|
-
|
7
|
+
class Post < ::Model
|
8
|
+
attributes :title, :body, :publish_at
|
9
|
+
associations :author, :comments
|
10
|
+
end
|
11
|
+
class Author < ::Model
|
12
|
+
attributes :first_name, :last_name
|
13
|
+
end
|
14
|
+
class Comment < ::Model
|
15
|
+
attributes :body
|
16
|
+
associations :author, :post
|
17
|
+
end
|
10
18
|
|
11
19
|
class PostSerializer < ActiveModel::Serializer
|
12
20
|
type 'posts'
|
data/test/cache_test.rb
CHANGED
@@ -4,6 +4,20 @@ require 'tempfile'
|
|
4
4
|
|
5
5
|
module ActiveModelSerializers
|
6
6
|
class CacheTest < ActiveSupport::TestCase
|
7
|
+
class Article < ::Model
|
8
|
+
attributes :title
|
9
|
+
# To confirm error is raised when cache_key is not set and cache_key option not passed to cache
|
10
|
+
undef_method :cache_key
|
11
|
+
end
|
12
|
+
class ArticleSerializer < ActiveModel::Serializer
|
13
|
+
cache only: [:place], skip_digest: true
|
14
|
+
attributes :title
|
15
|
+
end
|
16
|
+
|
17
|
+
class Author < ::Model
|
18
|
+
attributes :id, :name
|
19
|
+
associations :posts, :bio, :roles
|
20
|
+
end
|
7
21
|
# Instead of a primitive cache key (i.e. a string), this class
|
8
22
|
# returns a list of objects that require to be expanded themselves.
|
9
23
|
class AuthorWithExpandableCacheElements < Author
|
@@ -27,22 +41,73 @@ module ActiveModelSerializers
|
|
27
41
|
]
|
28
42
|
end
|
29
43
|
end
|
30
|
-
|
31
44
|
class UncachedAuthor < Author
|
32
45
|
# To confirm cache_key is set using updated_at and cache_key option passed to cache
|
33
46
|
undef_method :cache_key
|
34
47
|
end
|
48
|
+
class AuthorSerializer < ActiveModel::Serializer
|
49
|
+
cache key: 'writer', skip_digest: true
|
50
|
+
attributes :id, :name
|
35
51
|
|
36
|
-
|
37
|
-
|
38
|
-
|
52
|
+
has_many :posts
|
53
|
+
has_many :roles
|
54
|
+
has_one :bio
|
39
55
|
end
|
40
56
|
|
41
|
-
class
|
42
|
-
|
43
|
-
|
57
|
+
class Blog < ::Model
|
58
|
+
attributes :name
|
59
|
+
associations :writer
|
44
60
|
end
|
61
|
+
class BlogSerializer < ActiveModel::Serializer
|
62
|
+
cache key: 'blog'
|
63
|
+
attributes :id, :name
|
64
|
+
|
65
|
+
belongs_to :writer
|
66
|
+
end
|
67
|
+
|
68
|
+
class Comment < ::Model
|
69
|
+
attributes :id, :body
|
70
|
+
associations :post, :author
|
45
71
|
|
72
|
+
# Uses a custom non-time-based cache key
|
73
|
+
def cache_key
|
74
|
+
"comment/#{id}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
class CommentSerializer < ActiveModel::Serializer
|
78
|
+
cache expires_in: 1.day, skip_digest: true
|
79
|
+
attributes :id, :body
|
80
|
+
belongs_to :post
|
81
|
+
belongs_to :author
|
82
|
+
end
|
83
|
+
|
84
|
+
class Post < ::Model
|
85
|
+
attributes :id, :title, :body
|
86
|
+
associations :author, :comments, :blog
|
87
|
+
end
|
88
|
+
class PostSerializer < ActiveModel::Serializer
|
89
|
+
cache key: 'post', expires_in: 0.1, skip_digest: true
|
90
|
+
attributes :id, :title, :body
|
91
|
+
|
92
|
+
has_many :comments
|
93
|
+
belongs_to :blog
|
94
|
+
belongs_to :author
|
95
|
+
end
|
96
|
+
|
97
|
+
class Role < ::Model
|
98
|
+
attributes :name, :description, :special_attribute
|
99
|
+
associations :author
|
100
|
+
end
|
101
|
+
class RoleSerializer < ActiveModel::Serializer
|
102
|
+
cache only: [:name, :slug], skip_digest: true
|
103
|
+
attributes :id, :name, :description
|
104
|
+
attribute :friendly_id, key: :slug
|
105
|
+
belongs_to :author
|
106
|
+
|
107
|
+
def friendly_id
|
108
|
+
"#{object.name}-#{object.id}"
|
109
|
+
end
|
110
|
+
end
|
46
111
|
class InheritedRoleSerializer < RoleSerializer
|
47
112
|
cache key: 'inherited_role', only: [:name, :special_attribute]
|
48
113
|
attribute :special_attribute
|
@@ -51,10 +116,10 @@ module ActiveModelSerializers
|
|
51
116
|
setup do
|
52
117
|
cache_store.clear
|
53
118
|
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
54
|
-
@post = Post.new(title: 'New Post', body: 'Body')
|
119
|
+
@post = Post.new(id: 'post', title: 'New Post', body: 'Body')
|
55
120
|
@bio = Bio.new(id: 1, content: 'AMS Contributor')
|
56
|
-
@author = Author.new(name: 'Joao M. D. Moura')
|
57
|
-
@blog = Blog.new(id: 999, name: 'Custom blog', writer: @author
|
121
|
+
@author = Author.new(id: 'author', name: 'Joao M. D. Moura')
|
122
|
+
@blog = Blog.new(id: 999, name: 'Custom blog', writer: @author)
|
58
123
|
@role = Role.new(name: 'Great Author')
|
59
124
|
@location = Location.new(lat: '-23.550520', lng: '-46.633309')
|
60
125
|
@place = Place.new(name: 'Amazing Place')
|
@@ -117,7 +182,7 @@ module ActiveModelSerializers
|
|
117
182
|
def test_cache_key_definition
|
118
183
|
assert_equal('post', @post_serializer.class._cache_key)
|
119
184
|
assert_equal('writer', @author_serializer.class._cache_key)
|
120
|
-
|
185
|
+
assert_nil(@comment_serializer.class._cache_key)
|
121
186
|
end
|
122
187
|
|
123
188
|
def test_cache_key_interpolation_with_updated_at_when_cache_key_is_not_defined_on_object
|
@@ -160,7 +225,7 @@ module ActiveModelSerializers
|
|
160
225
|
|
161
226
|
def test_cache_options_definition
|
162
227
|
assert_equal({ expires_in: 0.1, skip_digest: true }, @post_serializer.class._cache_options)
|
163
|
-
|
228
|
+
assert_nil(@blog_serializer.class._cache_options)
|
164
229
|
assert_equal({ expires_in: 1.day, skip_digest: true }, @comment_serializer.class._cache_options)
|
165
230
|
end
|
166
231
|
|
@@ -171,8 +236,8 @@ module ActiveModelSerializers
|
|
171
236
|
|
172
237
|
def test_associations_separately_cache
|
173
238
|
cache_store.clear
|
174
|
-
|
175
|
-
|
239
|
+
assert_nil(cache_store.fetch(@post.cache_key))
|
240
|
+
assert_nil(cache_store.fetch(@comment.cache_key))
|
176
241
|
|
177
242
|
Timecop.freeze(Time.current) do
|
178
243
|
render_object_with_cache(@post)
|
@@ -244,7 +309,7 @@ module ActiveModelSerializers
|
|
244
309
|
# rubocop:disable Metrics/AbcSize
|
245
310
|
def test_a_serializer_rendered_by_two_adapter_returns_differently_fetch_attributes
|
246
311
|
Object.const_set(:Alert, Class.new(ActiveModelSerializers::Model) do
|
247
|
-
|
312
|
+
attributes :id, :status, :resource, :started_at, :ended_at, :updated_at, :created_at
|
248
313
|
end)
|
249
314
|
Object.const_set(:UncachedAlertSerializer, Class.new(ActiveModel::Serializer) do
|
250
315
|
attributes :id, :status, :resource, :started_at, :ended_at, :updated_at, :created_at
|
@@ -271,7 +336,7 @@ module ActiveModelSerializers
|
|
271
336
|
ended_at: nil,
|
272
337
|
updated_at: alert.updated_at,
|
273
338
|
created_at: alert.created_at
|
274
|
-
}
|
339
|
+
}.with_indifferent_access
|
275
340
|
expected_cached_jsonapi_attributes = {
|
276
341
|
id: '1',
|
277
342
|
type: 'alerts',
|
@@ -283,15 +348,15 @@ module ActiveModelSerializers
|
|
283
348
|
updated_at: alert.updated_at,
|
284
349
|
created_at: alert.created_at
|
285
350
|
}
|
286
|
-
}
|
351
|
+
}.with_indifferent_access
|
287
352
|
|
288
353
|
# Assert attributes are serialized correctly
|
289
354
|
serializable_alert = serializable(alert, serializer: AlertSerializer, adapter: :attributes)
|
290
|
-
attributes_serialization = serializable_alert.as_json
|
355
|
+
attributes_serialization = serializable_alert.as_json.with_indifferent_access
|
291
356
|
assert_equal expected_fetch_attributes, alert.attributes
|
292
357
|
assert_equal alert.attributes, attributes_serialization
|
293
358
|
attributes_cache_key = serializable_alert.adapter.serializer.cache_key(serializable_alert.adapter)
|
294
|
-
assert_equal attributes_serialization, cache_store.fetch(attributes_cache_key)
|
359
|
+
assert_equal attributes_serialization, cache_store.fetch(attributes_cache_key).with_indifferent_access
|
295
360
|
|
296
361
|
serializable_alert = serializable(alert, serializer: AlertSerializer, adapter: :json_api)
|
297
362
|
jsonapi_cache_key = serializable_alert.adapter.serializer.cache_key(serializable_alert.adapter)
|
@@ -303,7 +368,7 @@ module ActiveModelSerializers
|
|
303
368
|
serializable_alert = serializable(alert, serializer: UncachedAlertSerializer, adapter: :json_api)
|
304
369
|
assert_equal serializable_alert.as_json, jsonapi_serialization
|
305
370
|
|
306
|
-
cached_serialization = cache_store.fetch(jsonapi_cache_key)
|
371
|
+
cached_serialization = cache_store.fetch(jsonapi_cache_key).with_indifferent_access
|
307
372
|
assert_equal expected_cached_jsonapi_attributes, cached_serialization
|
308
373
|
ensure
|
309
374
|
Object.send(:remove_const, :Alert)
|
@@ -314,12 +379,14 @@ module ActiveModelSerializers
|
|
314
379
|
|
315
380
|
def test_uses_file_digest_in_cache_key
|
316
381
|
render_object_with_cache(@blog)
|
317
|
-
|
382
|
+
file_digest = Digest::MD5.hexdigest(File.open(__FILE__).read)
|
383
|
+
key = "#{@blog.cache_key}/#{adapter.cache_key}/#{file_digest}"
|
318
384
|
assert_equal(@blog_serializer.attributes, cache_store.fetch(key))
|
319
385
|
end
|
320
386
|
|
321
387
|
def test_cache_digest_definition
|
322
|
-
|
388
|
+
file_digest = Digest::MD5.hexdigest(File.open(__FILE__).read)
|
389
|
+
assert_equal(file_digest, @post_serializer.class._cache_digest)
|
323
390
|
end
|
324
391
|
|
325
392
|
def test_object_cache_keys
|
@@ -329,11 +396,15 @@ module ActiveModelSerializers
|
|
329
396
|
actual = ActiveModel::Serializer.object_cache_keys(serializable.adapter.serializer, serializable.adapter, include_directive)
|
330
397
|
|
331
398
|
assert_equal 3, actual.size
|
332
|
-
|
333
|
-
assert actual.any? { |key| key
|
334
|
-
|
399
|
+
expected_key = "comment/1/#{serializable.adapter.cache_key}"
|
400
|
+
assert actual.any? { |key| key == expected_key }, "actual '#{actual}' should include #{expected_key}"
|
401
|
+
expected_key = %r{post/post-\d+}
|
402
|
+
assert actual.any? { |key| key =~ expected_key }, "actual '#{actual}' should match '#{expected_key}'"
|
403
|
+
expected_key = %r{author/author-\d+}
|
404
|
+
assert actual.any? { |key| key =~ expected_key }, "actual '#{actual}' should match '#{expected_key}'"
|
335
405
|
end
|
336
406
|
|
407
|
+
# rubocop:disable Metrics/AbcSize
|
337
408
|
def test_fetch_attributes_from_cache
|
338
409
|
serializers = ActiveModel::Serializer::CollectionSerializer.new([@comment, @comment])
|
339
410
|
|
@@ -344,10 +415,10 @@ module ActiveModelSerializers
|
|
344
415
|
adapter_options = {}
|
345
416
|
adapter_instance = ActiveModelSerializers::Adapter::Attributes.new(serializers, adapter_options)
|
346
417
|
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
347
|
-
cached_attributes = adapter_options.fetch(:cached_attributes)
|
418
|
+
cached_attributes = adapter_options.fetch(:cached_attributes).with_indifferent_access
|
348
419
|
|
349
420
|
include_directive = ActiveModelSerializers.default_include_directive
|
350
|
-
manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive)
|
421
|
+
manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive).with_indifferent_access
|
351
422
|
assert_equal manual_cached_attributes, cached_attributes
|
352
423
|
|
353
424
|
assert_equal cached_attributes["#{@comment.cache_key}/#{adapter_instance.cache_key}"], Comment.new(id: 1, body: 'ZOMG A COMMENT').attributes
|
@@ -358,6 +429,7 @@ module ActiveModelSerializers
|
|
358
429
|
assert_equal cached_attributes["#{writer_cache_key}/#{adapter_instance.cache_key}"], Author.new(id: 'author', name: 'Joao M. D. Moura').attributes
|
359
430
|
end
|
360
431
|
end
|
432
|
+
# rubocop:enable Metrics/AbcSize
|
361
433
|
|
362
434
|
def test_cache_read_multi_with_fragment_cache_enabled
|
363
435
|
post_serializer = Class.new(ActiveModel::Serializer) do
|
@@ -516,7 +588,7 @@ module ActiveModelSerializers
|
|
516
588
|
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|
517
589
|
assert_equal(role_hash, expected_result)
|
518
590
|
|
519
|
-
role.
|
591
|
+
role.id = 'this has been updated'
|
520
592
|
role.name = 'this was cached'
|
521
593
|
|
522
594
|
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|