active_model_serializers 0.10.0 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -2
- data/Gemfile +1 -1
- data/README.md +21 -24
- data/active_model_serializers.gemspec +4 -8
- data/docs/general/adapters.md +4 -2
- data/docs/general/configuration_options.md +6 -1
- data/docs/general/deserialization.md +1 -1
- data/docs/general/serializers.md +30 -3
- data/docs/jsonapi/schema.md +1 -1
- data/lib/active_model/serializer.rb +54 -11
- data/lib/active_model/serializer/adapter/base.rb +2 -0
- data/lib/active_model/serializer/associations.rb +4 -5
- data/lib/active_model/serializer/belongs_to_reflection.rb +0 -3
- data/lib/active_model/serializer/caching.rb +62 -110
- data/lib/active_model/serializer/collection_serializer.rb +30 -10
- data/lib/active_model/serializer/configuration.rb +1 -0
- data/lib/active_model/serializer/has_many_reflection.rb +0 -3
- data/lib/active_model/serializer/has_one_reflection.rb +0 -3
- data/lib/active_model/serializer/reflection.rb +3 -3
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model_serializers.rb +6 -0
- data/lib/active_model_serializers/adapter.rb +6 -0
- data/lib/active_model_serializers/adapter/attributes.rb +2 -67
- data/lib/active_model_serializers/adapter/base.rb +38 -38
- data/lib/active_model_serializers/adapter/json_api.rb +36 -28
- data/lib/active_model_serializers/adapter/json_api/link.rb +1 -1
- data/lib/active_model_serializers/adapter/json_api/pagination_links.rb +8 -1
- data/lib/active_model_serializers/deprecate.rb +1 -2
- data/lib/active_model_serializers/deserialization.rb +2 -0
- data/lib/active_model_serializers/model.rb +2 -0
- data/lib/active_model_serializers/railtie.rb +2 -0
- data/lib/active_model_serializers/register_jsonapi_renderer.rb +34 -23
- data/lib/active_model_serializers/serialization_context.rb +10 -3
- data/lib/grape/formatters/active_model_serializers.rb +19 -2
- data/lib/grape/helpers/active_model_serializers.rb +1 -0
- data/test/action_controller/adapter_selector_test.rb +1 -1
- data/test/action_controller/explicit_serializer_test.rb +5 -4
- data/test/action_controller/json/include_test.rb +106 -27
- data/test/action_controller/json_api/errors_test.rb +2 -2
- data/test/action_controller/json_api/linked_test.rb +26 -21
- data/test/action_controller/serialization_test.rb +9 -6
- data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +143 -0
- data/test/active_model_serializers/serialization_context_test_isolated.rb +23 -10
- data/test/adapter/json/collection_test.rb +14 -0
- data/test/adapter/json_api/collection_test.rb +4 -3
- data/test/adapter/json_api/errors_test.rb +13 -15
- data/test/adapter/json_api/linked_test.rb +8 -5
- data/test/adapter/json_api/links_test.rb +3 -1
- data/test/adapter/json_api/pagination_links_test.rb +13 -1
- data/test/adapter/json_api/relationships_test.rb +9 -4
- data/test/adapter/json_api/resource_identifier_test.rb +7 -2
- data/test/adapter/json_api/transform_test.rb +76 -75
- data/test/adapter/json_test.rb +4 -3
- data/test/benchmark/app.rb +1 -1
- data/test/benchmark/bm_caching.rb +14 -14
- data/test/benchmark/bm_transform.rb +16 -5
- data/test/benchmark/controllers.rb +16 -17
- data/test/benchmark/fixtures.rb +72 -72
- data/test/cache_test.rb +73 -45
- data/test/fixtures/poro.rb +6 -5
- data/test/grape_test.rb +96 -2
- data/test/serializable_resource_test.rb +12 -12
- data/test/serializers/meta_test.rb +12 -6
- data/test/support/isolated_unit.rb +1 -0
- data/test/support/rails5_shims.rb +8 -2
- data/test/support/rails_app.rb +0 -9
- metadata +53 -23
- data/lib/active_model/serializer/include_tree.rb +0 -111
- data/test/include_tree/from_include_args_test.rb +0 -26
- data/test/include_tree/from_string_test.rb +0 -94
- data/test/include_tree/include_args_to_hash_test.rb +0 -64
data/test/adapter/json_test.rb
CHANGED
@@ -33,9 +33,10 @@ module ActiveModelSerializers
|
|
33
33
|
|
34
34
|
assert_equal({
|
35
35
|
id: 1,
|
36
|
-
reviews: [
|
37
|
-
|
38
|
-
|
36
|
+
reviews: [
|
37
|
+
{ id: 1, body: 'ZOMG A COMMENT' },
|
38
|
+
{ id: 2, body: 'ZOMG ANOTHER COMMENT' }
|
39
|
+
],
|
39
40
|
writer: { id: 1, name: 'Steve K.' },
|
40
41
|
site: { id: 1, name: 'My Blog!!' }
|
41
42
|
}, adapter.serializable_hash[:post])
|
data/test/benchmark/app.rb
CHANGED
@@ -43,7 +43,7 @@ class BenchmarkApp < Rails::Application
|
|
43
43
|
config.secret_key_base = 'abc123'
|
44
44
|
config.consider_all_requests_local = false
|
45
45
|
|
46
|
-
# otherwise deadlock
|
46
|
+
# otherwise deadlock occurred
|
47
47
|
config.middleware.delete 'Rack::Lock'
|
48
48
|
|
49
49
|
# to disable log files
|
@@ -66,25 +66,25 @@ class ApiAssertion
|
|
66
66
|
def expected
|
67
67
|
@expected ||=
|
68
68
|
{
|
69
|
-
'
|
70
|
-
'id' =>
|
71
|
-
'title' => 'New
|
69
|
+
'primary_resource' => {
|
70
|
+
'id' => 1337,
|
71
|
+
'title' => 'New PrimaryResource',
|
72
72
|
'body' => 'Body',
|
73
|
-
'
|
74
|
-
|
75
|
-
|
76
|
-
'body' => 'ZOMG A COMMENT'
|
77
|
-
}
|
78
|
-
],
|
79
|
-
'blog' => {
|
80
|
-
'id' => 999,
|
81
|
-
'name' => 'Custom blog'
|
73
|
+
'virtual_attribute' => {
|
74
|
+
'id' => 999,
|
75
|
+
'name' => 'Free-Range Virtual Attribute'
|
82
76
|
},
|
83
|
-
'
|
77
|
+
'has_one_relationship' => {
|
84
78
|
'id' => 42,
|
85
79
|
'first_name' => 'Joao',
|
86
80
|
'last_name' => 'Moura'
|
87
|
-
}
|
81
|
+
},
|
82
|
+
'has_many_relationships' => [
|
83
|
+
{
|
84
|
+
'id' => 1,
|
85
|
+
'body' => 'ZOMG A HAS MANY RELATIONSHIP'
|
86
|
+
}
|
87
|
+
]
|
88
88
|
}
|
89
89
|
}
|
90
90
|
end
|
@@ -4,12 +4,23 @@ require_relative './app'
|
|
4
4
|
time = 10
|
5
5
|
disable_gc = true
|
6
6
|
ActiveModelSerializers.config.key_transform = :unaltered
|
7
|
-
|
8
|
-
|
7
|
+
has_many_relationships = (0..50).map do |i|
|
8
|
+
HasManyRelationship.new(id: i, body: 'ZOMG A HAS MANY RELATIONSHIP')
|
9
9
|
end
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
has_one_relationship = HasOneRelationship.new(
|
11
|
+
id: 42,
|
12
|
+
first_name: 'Joao',
|
13
|
+
last_name: 'Moura'
|
14
|
+
)
|
15
|
+
primary_resource = PrimaryResource.new(
|
16
|
+
id: 1337,
|
17
|
+
title: 'New PrimaryResource',
|
18
|
+
virtual_attribute: nil,
|
19
|
+
body: 'Body',
|
20
|
+
has_many_relationships: has_many_relationships,
|
21
|
+
has_one_relationship: has_one_relationship
|
22
|
+
)
|
23
|
+
serializer = PrimaryResourceSerializer.new(primary_resource)
|
13
24
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
14
25
|
serialization = adapter.as_json
|
15
26
|
|
@@ -1,31 +1,30 @@
|
|
1
|
-
class
|
2
|
-
|
1
|
+
class PrimaryResourceController < ActionController::Base
|
2
|
+
PRIMARY_RESOURCE =
|
3
3
|
begin
|
4
|
-
updated_at = Time.current
|
5
4
|
if ENV['BENCH_STRESS']
|
6
|
-
|
7
|
-
|
5
|
+
has_many_relationships = (0..50).map do |i|
|
6
|
+
HasManyRelationship.new(id: i, body: 'ZOMG A HAS MANY RELATIONSHIP')
|
8
7
|
end
|
9
8
|
else
|
10
|
-
|
9
|
+
has_many_relationships = [HasManyRelationship.new(id: 1, body: 'ZOMG A HAS MANY RELATIONSHIP')]
|
11
10
|
end
|
12
|
-
|
13
|
-
|
11
|
+
has_one_relationship = HasOneRelationship.new(id: 42, first_name: 'Joao', last_name: 'Moura')
|
12
|
+
PrimaryResource.new(id: 1337, title: 'New PrimaryResource', virtual_attribute: nil, body: 'Body', has_many_relationships: has_many_relationships, has_one_relationship: has_one_relationship)
|
14
13
|
end
|
15
14
|
|
16
15
|
def render_with_caching_serializer
|
17
16
|
toggle_cache_status
|
18
|
-
render json:
|
17
|
+
render json: PRIMARY_RESOURCE, serializer: CachingPrimaryResourceSerializer, adapter: :json, meta: { caching: perform_caching }
|
19
18
|
end
|
20
19
|
|
21
20
|
def render_with_fragment_caching_serializer
|
22
21
|
toggle_cache_status
|
23
|
-
render json:
|
22
|
+
render json: PRIMARY_RESOURCE, serializer: FragmentCachingPrimaryResourceSerializer, adapter: :json, meta: { caching: perform_caching }
|
24
23
|
end
|
25
24
|
|
26
25
|
def render_with_non_caching_serializer
|
27
26
|
toggle_cache_status
|
28
|
-
render json:
|
27
|
+
render json: PRIMARY_RESOURCE, adapter: :json, meta: { caching: perform_caching }
|
29
28
|
end
|
30
29
|
|
31
30
|
def render_cache_status
|
@@ -33,7 +32,7 @@ class PostController < ActionController::Base
|
|
33
32
|
# Uncomment to debug
|
34
33
|
# STDERR.puts cache_store.class
|
35
34
|
# STDERR.puts cache_dependencies
|
36
|
-
# ActiveSupport::Cache::Store.logger.debug [ActiveModelSerializers.config.cache_store, ActiveModelSerializers.config.perform_caching,
|
35
|
+
# ActiveSupport::Cache::Store.logger.debug [ActiveModelSerializers.config.cache_store, ActiveModelSerializers.config.perform_caching, CachingPrimaryResourceSerializer._cache, perform_caching, params].inspect
|
37
36
|
render json: { caching: perform_caching, meta: { cache_log: cache_messages, cache_status: cache_status } }.to_json
|
38
37
|
end
|
39
38
|
|
@@ -76,9 +75,9 @@ class PostController < ActionController::Base
|
|
76
75
|
end
|
77
76
|
|
78
77
|
Rails.application.routes.draw do
|
79
|
-
get '/status(/:on)' => '
|
80
|
-
get '/clear' => '
|
81
|
-
get '/caching(/:on)' => '
|
82
|
-
get '/fragment_caching(/:on)' => '
|
83
|
-
get '/non_caching(/:on)' => '
|
78
|
+
get '/status(/:on)' => 'primary_resource#render_cache_status'
|
79
|
+
get '/clear' => 'primary_resource#clear'
|
80
|
+
get '/caching(/:on)' => 'primary_resource#render_with_caching_serializer'
|
81
|
+
get '/fragment_caching(/:on)' => 'primary_resource#render_with_fragment_caching_serializer'
|
82
|
+
get '/non_caching(/:on)' => 'primary_resource#render_with_non_caching_serializer'
|
84
83
|
end
|
data/test/benchmark/fixtures.rb
CHANGED
@@ -1,33 +1,33 @@
|
|
1
1
|
Rails.configuration.serializers = []
|
2
|
-
class
|
2
|
+
class HasOneRelationshipSerializer < ActiveModel::Serializer
|
3
3
|
attributes :id, :first_name, :last_name
|
4
4
|
|
5
|
-
has_many :
|
5
|
+
has_many :primary_resources, embed: :ids
|
6
6
|
has_one :bio
|
7
7
|
end
|
8
|
-
Rails.configuration.serializers <<
|
8
|
+
Rails.configuration.serializers << HasOneRelationshipSerializer
|
9
9
|
|
10
|
-
class
|
10
|
+
class VirtualAttributeSerializer < ActiveModel::Serializer
|
11
11
|
attributes :id, :name
|
12
12
|
end
|
13
|
-
Rails.configuration.serializers <<
|
13
|
+
Rails.configuration.serializers << VirtualAttributeSerializer
|
14
14
|
|
15
|
-
class
|
16
|
-
attributes :id, :body
|
15
|
+
class HasManyRelationshipSerializer < ActiveModel::Serializer
|
16
|
+
attributes :id, :body
|
17
17
|
|
18
|
-
belongs_to :
|
19
|
-
belongs_to :
|
18
|
+
belongs_to :primary_resource
|
19
|
+
belongs_to :has_one_relationship
|
20
20
|
end
|
21
|
-
Rails.configuration.serializers <<
|
21
|
+
Rails.configuration.serializers << HasManyRelationshipSerializer
|
22
22
|
|
23
|
-
class
|
23
|
+
class PrimaryResourceSerializer < ActiveModel::Serializer
|
24
24
|
attributes :id, :title, :body
|
25
25
|
|
26
|
-
has_many :
|
27
|
-
belongs_to :
|
28
|
-
belongs_to :
|
26
|
+
has_many :has_many_relationships, serializer: HasManyRelationshipSerializer
|
27
|
+
belongs_to :virtual_attribute, serializer: VirtualAttributeSerializer
|
28
|
+
belongs_to :has_one_relationship, serializer: HasOneRelationshipSerializer
|
29
29
|
|
30
|
-
link(:
|
30
|
+
link(:primary_resource_has_one_relationships) { 'https://example.com/primary_resource_has_one_relationships' }
|
31
31
|
|
32
32
|
meta do
|
33
33
|
{
|
@@ -36,33 +36,33 @@ class PostSerializer < ActiveModel::Serializer
|
|
36
36
|
}
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
40
|
-
|
39
|
+
def virtual_attribute
|
40
|
+
VirtualAttribute.new(id: 999, name: 'Free-Range Virtual Attribute')
|
41
41
|
end
|
42
42
|
end
|
43
|
-
Rails.configuration.serializers <<
|
43
|
+
Rails.configuration.serializers << PrimaryResourceSerializer
|
44
44
|
|
45
|
-
class
|
45
|
+
class CachingHasOneRelationshipSerializer < HasOneRelationshipSerializer
|
46
46
|
cache key: 'writer', skip_digest: true
|
47
47
|
end
|
48
|
-
Rails.configuration.serializers <<
|
48
|
+
Rails.configuration.serializers << CachingHasOneRelationshipSerializer
|
49
49
|
|
50
|
-
class
|
50
|
+
class CachingHasManyRelationshipSerializer < HasManyRelationshipSerializer
|
51
51
|
cache expires_in: 1.day, skip_digest: true
|
52
52
|
end
|
53
|
-
Rails.configuration.serializers <<
|
53
|
+
Rails.configuration.serializers << CachingHasManyRelationshipSerializer
|
54
54
|
|
55
55
|
# see https://github.com/rails-api/active_model_serializers/pull/1690/commits/68715b8f99bc29677e8a47bb3f305f23c077024b#r60344532
|
56
|
-
class
|
57
|
-
cache key: '
|
56
|
+
class CachingPrimaryResourceSerializer < ActiveModel::Serializer
|
57
|
+
cache key: 'primary_resource', expires_in: 0.1, skip_digest: true
|
58
58
|
|
59
59
|
attributes :id, :title, :body
|
60
60
|
|
61
|
-
belongs_to :
|
62
|
-
belongs_to :
|
63
|
-
has_many :
|
61
|
+
belongs_to :virtual_attribute, serializer: VirtualAttributeSerializer
|
62
|
+
belongs_to :has_one_relationship, serializer: CachingHasOneRelationshipSerializer
|
63
|
+
has_many :has_many_relationships, serializer: CachingHasManyRelationshipSerializer
|
64
64
|
|
65
|
-
link(:
|
65
|
+
link(:primary_resource_has_one_relationships) { 'https://example.com/primary_resource_has_one_relationships' }
|
66
66
|
|
67
67
|
meta do
|
68
68
|
{
|
@@ -71,33 +71,33 @@ class CachingPostSerializer < ActiveModel::Serializer
|
|
71
71
|
}
|
72
72
|
end
|
73
73
|
|
74
|
-
def
|
75
|
-
|
74
|
+
def virtual_attribute
|
75
|
+
VirtualAttribute.new(id: 999, name: 'Free-Range Virtual Attribute')
|
76
76
|
end
|
77
77
|
end
|
78
|
-
Rails.configuration.serializers <<
|
78
|
+
Rails.configuration.serializers << CachingPrimaryResourceSerializer
|
79
79
|
|
80
|
-
class
|
80
|
+
class FragmentCachingHasOneRelationshipSerializer < HasOneRelationshipSerializer
|
81
81
|
cache key: 'writer', only: [:first_name, :last_name], skip_digest: true
|
82
82
|
end
|
83
|
-
Rails.configuration.serializers <<
|
83
|
+
Rails.configuration.serializers << FragmentCachingHasOneRelationshipSerializer
|
84
84
|
|
85
|
-
class
|
86
|
-
cache expires_in: 1.day, except: [:
|
85
|
+
class FragmentCachingHasManyRelationshipSerializer < HasManyRelationshipSerializer
|
86
|
+
cache expires_in: 1.day, except: [:body], skip_digest: true
|
87
87
|
end
|
88
|
-
Rails.configuration.serializers <<
|
88
|
+
Rails.configuration.serializers << CachingHasManyRelationshipSerializer
|
89
89
|
|
90
90
|
# see https://github.com/rails-api/active_model_serializers/pull/1690/commits/68715b8f99bc29677e8a47bb3f305f23c077024b#r60344532
|
91
|
-
class
|
92
|
-
cache key: '
|
91
|
+
class FragmentCachingPrimaryResourceSerializer < ActiveModel::Serializer
|
92
|
+
cache key: 'primary_resource', expires_in: 0.1, skip_digest: true
|
93
93
|
|
94
94
|
attributes :id, :title, :body
|
95
95
|
|
96
|
-
belongs_to :
|
97
|
-
belongs_to :
|
98
|
-
has_many :
|
96
|
+
belongs_to :virtual_attribute, serializer: VirtualAttributeSerializer
|
97
|
+
belongs_to :has_one_relationship, serializer: FragmentCachingHasOneRelationshipSerializer
|
98
|
+
has_many :has_many_relationships, serializer: FragmentCachingHasManyRelationshipSerializer
|
99
99
|
|
100
|
-
link(:
|
100
|
+
link(:primary_resource_has_one_relationships) { 'https://example.com/primary_resource_has_one_relationships' }
|
101
101
|
|
102
102
|
meta do
|
103
103
|
{
|
@@ -106,11 +106,11 @@ class FragmentCachingPostSerializer < ActiveModel::Serializer
|
|
106
106
|
}
|
107
107
|
end
|
108
108
|
|
109
|
-
def
|
110
|
-
|
109
|
+
def virtual_attribute
|
110
|
+
VirtualAttribute.new(id: 999, name: 'Free-Range Virtual Attribute')
|
111
111
|
end
|
112
112
|
end
|
113
|
-
Rails.configuration.serializers <<
|
113
|
+
Rails.configuration.serializers << FragmentCachingPrimaryResourceSerializer
|
114
114
|
|
115
115
|
if ENV['ENABLE_ACTIVE_RECORD'] == 'true'
|
116
116
|
require 'active_record'
|
@@ -119,48 +119,48 @@ if ENV['ENABLE_ACTIVE_RECORD'] == 'true'
|
|
119
119
|
ActiveRecord::Schema.define do
|
120
120
|
self.verbose = false
|
121
121
|
|
122
|
-
create_table :
|
122
|
+
create_table :virtual_attributes, force: true do |t|
|
123
123
|
t.string :name
|
124
124
|
t.timestamps null: false
|
125
125
|
end
|
126
|
-
create_table :
|
126
|
+
create_table :has_one_relationships, force: true do |t|
|
127
127
|
t.string :first_name
|
128
128
|
t.string :last_name
|
129
129
|
t.timestamps null: false
|
130
130
|
end
|
131
|
-
create_table :
|
131
|
+
create_table :primary_resources, force: true do |t|
|
132
132
|
t.string :title
|
133
133
|
t.text :body
|
134
|
-
t.references :
|
135
|
-
t.references :
|
134
|
+
t.references :has_one_relationship
|
135
|
+
t.references :virtual_attribute
|
136
136
|
t.timestamps null: false
|
137
137
|
end
|
138
|
-
create_table :
|
138
|
+
create_table :has_many_relationships, force: true do |t|
|
139
139
|
t.text :body
|
140
|
-
t.references :
|
141
|
-
t.references :
|
140
|
+
t.references :has_one_relationship
|
141
|
+
t.references :primary_resource
|
142
142
|
t.timestamps null: false
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
146
|
-
class
|
147
|
-
belongs_to :
|
148
|
-
belongs_to :
|
146
|
+
class HasManyRelationship < ActiveRecord::Base
|
147
|
+
belongs_to :has_one_relationship
|
148
|
+
belongs_to :primary_resource
|
149
149
|
end
|
150
150
|
|
151
|
-
class
|
152
|
-
has_many :
|
153
|
-
has_many :
|
151
|
+
class HasOneRelationship < ActiveRecord::Base
|
152
|
+
has_many :primary_resources
|
153
|
+
has_many :has_many_relationships
|
154
154
|
end
|
155
155
|
|
156
|
-
class
|
157
|
-
has_many :
|
158
|
-
belongs_to :
|
159
|
-
belongs_to :
|
156
|
+
class PrimaryResource < ActiveRecord::Base
|
157
|
+
has_many :has_many_relationships
|
158
|
+
belongs_to :has_one_relationship
|
159
|
+
belongs_to :virtual_attribute
|
160
160
|
end
|
161
161
|
|
162
|
-
class
|
163
|
-
has_many :
|
162
|
+
class VirtualAttribute < ActiveRecord::Base
|
163
|
+
has_many :primary_resources
|
164
164
|
end
|
165
165
|
else
|
166
166
|
# ActiveModelSerializers::Model is a convenient
|
@@ -201,19 +201,19 @@ else
|
|
201
201
|
end
|
202
202
|
end
|
203
203
|
|
204
|
-
class
|
205
|
-
attr_accessor :id, :body
|
204
|
+
class HasManyRelationship < BenchmarkModel
|
205
|
+
attr_accessor :id, :body
|
206
206
|
end
|
207
207
|
|
208
|
-
class
|
209
|
-
attr_accessor :id, :first_name, :last_name, :
|
208
|
+
class HasOneRelationship < BenchmarkModel
|
209
|
+
attr_accessor :id, :first_name, :last_name, :primary_resources
|
210
210
|
end
|
211
211
|
|
212
|
-
class
|
213
|
-
attr_accessor :id, :title, :body, :
|
212
|
+
class PrimaryResource < BenchmarkModel
|
213
|
+
attr_accessor :id, :title, :body, :has_many_relationships, :virtual_attribute, :has_one_relationship
|
214
214
|
end
|
215
215
|
|
216
|
-
class
|
216
|
+
class VirtualAttribute < BenchmarkModel
|
217
217
|
attr_accessor :id, :name
|
218
218
|
end
|
219
219
|
end
|
data/test/cache_test.rb
CHANGED
@@ -102,13 +102,13 @@ module ActiveModelSerializers
|
|
102
102
|
|
103
103
|
render_object_with_cache(uncached_author)
|
104
104
|
key = "#{uncached_author_serializer.class._cache_key}/#{uncached_author_serializer.object.id}-#{uncached_author_serializer.object.updated_at.strftime("%Y%m%d%H%M%S%9N")}"
|
105
|
-
key = "#{key}/#{adapter.
|
105
|
+
key = "#{key}/#{adapter.cache_key}"
|
106
106
|
assert_equal(uncached_author_serializer.attributes.to_json, cache_store.fetch(key).to_json)
|
107
107
|
end
|
108
108
|
|
109
109
|
def test_default_cache_key_fallback
|
110
110
|
render_object_with_cache(@comment)
|
111
|
-
key = "#{@comment.cache_key}/#{adapter.
|
111
|
+
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
112
112
|
assert_equal(@comment_serializer.attributes.to_json, cache_store.fetch(key).to_json)
|
113
113
|
end
|
114
114
|
|
@@ -117,7 +117,7 @@ module ActiveModelSerializers
|
|
117
117
|
e = assert_raises ActiveModel::Serializer::UndefinedCacheKey do
|
118
118
|
render_object_with_cache(article)
|
119
119
|
end
|
120
|
-
assert_match(/ActiveModelSerializers::CacheTest::Article must define #cache_key, or the 'key:' option must be passed into '
|
120
|
+
assert_match(/ActiveModelSerializers::CacheTest::Article must define #cache_key, or the 'key:' option must be passed into 'ActiveModelSerializers::CacheTest::ArticleSerializer.cache'/, e.message)
|
121
121
|
end
|
122
122
|
|
123
123
|
def test_cache_options_definition
|
@@ -127,7 +127,7 @@ module ActiveModelSerializers
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def test_fragment_cache_definition
|
130
|
-
assert_equal([:name], @role_serializer.class._cache_only)
|
130
|
+
assert_equal([:name, :slug], @role_serializer.class._cache_only)
|
131
131
|
assert_equal([:content], @bio_serializer.class._cache_except)
|
132
132
|
end
|
133
133
|
|
@@ -139,9 +139,9 @@ module ActiveModelSerializers
|
|
139
139
|
Timecop.freeze(Time.current) do
|
140
140
|
render_object_with_cache(@post)
|
141
141
|
|
142
|
-
key = "#{@post.cache_key}/#{adapter.
|
142
|
+
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
143
143
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
144
|
-
key = "#{@comment.cache_key}/#{adapter.
|
144
|
+
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
145
145
|
assert_equal(@comment_serializer.attributes, cache_store.fetch(key))
|
146
146
|
end
|
147
147
|
end
|
@@ -152,9 +152,9 @@ module ActiveModelSerializers
|
|
152
152
|
render_object_with_cache(@post)
|
153
153
|
|
154
154
|
# Check if it cached the objects separately
|
155
|
-
key = "#{@post.cache_key}/#{adapter.
|
155
|
+
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
156
156
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
157
|
-
key = "#{@comment.cache_key}/#{adapter.
|
157
|
+
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
158
158
|
assert_equal(@comment_serializer.attributes, cache_store.fetch(key))
|
159
159
|
|
160
160
|
# Simulating update on comments relationship with Post
|
@@ -166,9 +166,9 @@ module ActiveModelSerializers
|
|
166
166
|
render_object_with_cache(@post)
|
167
167
|
|
168
168
|
# Check if the the new comment was cached
|
169
|
-
key = "#{new_comment.cache_key}/#{adapter.
|
169
|
+
key = "#{new_comment.cache_key}/#{adapter.cache_key}"
|
170
170
|
assert_equal(new_comment_serializer.attributes, cache_store.fetch(key))
|
171
|
-
key = "#{@post.cache_key}/#{adapter.
|
171
|
+
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
172
172
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
173
173
|
end
|
174
174
|
end
|
@@ -178,14 +178,14 @@ module ActiveModelSerializers
|
|
178
178
|
id: @location.id,
|
179
179
|
lat: @location.lat,
|
180
180
|
lng: @location.lng,
|
181
|
-
|
181
|
+
address: 'Nowhere'
|
182
182
|
}
|
183
183
|
|
184
184
|
hash = render_object_with_cache(@location)
|
185
185
|
|
186
186
|
assert_equal(hash, expected_result)
|
187
|
-
key = "#{@location.cache_key}/#{adapter.
|
188
|
-
assert_equal({
|
187
|
+
key = "#{@location.cache_key}/#{adapter.cache_key}"
|
188
|
+
assert_equal({ address: 'Nowhere' }, cache_store.fetch(key))
|
189
189
|
end
|
190
190
|
|
191
191
|
def test_fragment_cache_with_inheritance
|
@@ -204,7 +204,7 @@ module ActiveModelSerializers
|
|
204
204
|
|
205
205
|
# Based on original failing test by @kevintyll
|
206
206
|
# rubocop:disable Metrics/AbcSize
|
207
|
-
def
|
207
|
+
def test_a_serializer_rendered_by_two_adapter_returns_differently_fetch_attributes
|
208
208
|
Object.const_set(:Alert, Class.new(ActiveModelSerializers::Model) do
|
209
209
|
attr_accessor :id, :status, :resource, :started_at, :ended_at, :updated_at, :created_at
|
210
210
|
end)
|
@@ -225,7 +225,7 @@ module ActiveModelSerializers
|
|
225
225
|
created_at: Time.new(2016, 3, 31, 21, 37, 35, 0)
|
226
226
|
)
|
227
227
|
|
228
|
-
|
228
|
+
expected_fetch_attributes = {
|
229
229
|
id: 1,
|
230
230
|
status: 'fail',
|
231
231
|
resource: 'resource-1',
|
@@ -250,7 +250,7 @@ module ActiveModelSerializers
|
|
250
250
|
# Assert attributes are serialized correctly
|
251
251
|
serializable_alert = serializable(alert, serializer: AlertSerializer, adapter: :attributes)
|
252
252
|
attributes_serialization = serializable_alert.as_json
|
253
|
-
assert_equal
|
253
|
+
assert_equal expected_fetch_attributes, alert.attributes
|
254
254
|
assert_equal alert.attributes, attributes_serialization
|
255
255
|
attributes_cache_key = serializable_alert.adapter.serializer.cache_key(serializable_alert.adapter)
|
256
256
|
assert_equal attributes_serialization, cache_store.fetch(attributes_cache_key)
|
@@ -276,7 +276,7 @@ module ActiveModelSerializers
|
|
276
276
|
|
277
277
|
def test_uses_file_digest_in_cache_key
|
278
278
|
render_object_with_cache(@blog)
|
279
|
-
key = "#{@blog.cache_key}/#{adapter.
|
279
|
+
key = "#{@blog.cache_key}/#{adapter.cache_key}/#{::Model::FILE_DIGEST}"
|
280
280
|
assert_equal(@blog_serializer.attributes, cache_store.fetch(key))
|
281
281
|
end
|
282
282
|
|
@@ -286,33 +286,38 @@ module ActiveModelSerializers
|
|
286
286
|
|
287
287
|
def test_object_cache_keys
|
288
288
|
serializable = ActiveModelSerializers::SerializableResource.new([@comment, @comment])
|
289
|
-
|
289
|
+
include_directive = JSONAPI::IncludeDirective.new('*', allow_wildcard: true)
|
290
290
|
|
291
|
-
actual = ActiveModel::Serializer.object_cache_keys(serializable.adapter.serializer, serializable.adapter,
|
291
|
+
actual = ActiveModel::Serializer.object_cache_keys(serializable.adapter.serializer, serializable.adapter, include_directive)
|
292
292
|
|
293
293
|
assert_equal 3, actual.size
|
294
|
-
assert actual.any? { |key| key == "comment/1/#{serializable.adapter.
|
294
|
+
assert actual.any? { |key| key == "comment/1/#{serializable.adapter.cache_key}" }
|
295
295
|
assert actual.any? { |key| key =~ %r{post/post-\d+} }
|
296
296
|
assert actual.any? { |key| key =~ %r{author/author-\d+} }
|
297
297
|
end
|
298
298
|
|
299
|
-
def
|
300
|
-
|
299
|
+
def test_fetch_attributes_from_cache
|
300
|
+
serializers = ActiveModel::Serializer::CollectionSerializer.new([@comment, @comment])
|
301
301
|
|
302
302
|
Timecop.freeze(Time.current) do
|
303
303
|
render_object_with_cache(@comment)
|
304
304
|
|
305
|
-
|
306
|
-
|
307
|
-
|
305
|
+
options = {}
|
306
|
+
adapter_options = {}
|
307
|
+
adapter_instance = ActiveModelSerializers::Adapter::Attributes.new(serializers, adapter_options)
|
308
|
+
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
309
|
+
cached_attributes = adapter_options.fetch(:cached_attributes)
|
308
310
|
|
309
|
-
|
310
|
-
|
311
|
+
include_directive = ActiveModelSerializers.default_include_directive
|
312
|
+
manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive)
|
313
|
+
assert_equal manual_cached_attributes, cached_attributes
|
314
|
+
|
315
|
+
assert_equal cached_attributes["#{@comment.cache_key}/#{adapter_instance.cache_key}"], Comment.new(id: 1, body: 'ZOMG A COMMENT').attributes
|
316
|
+
assert_equal cached_attributes["#{@comment.post.cache_key}/#{adapter_instance.cache_key}"], Post.new(id: 'post', title: 'New Post', body: 'Body').attributes
|
311
317
|
|
312
318
|
writer = @comment.post.blog.writer
|
313
319
|
writer_cache_key = writer.cache_key
|
314
|
-
|
315
|
-
assert_equal cached_attributes["#{writer_cache_key}/#{attributes.cached_name}"], Author.new(id: 'author', name: 'Joao M. D. Moura').attributes
|
320
|
+
assert_equal cached_attributes["#{writer_cache_key}/#{adapter_instance.cache_key}"], Author.new(id: 'author', name: 'Joao M. D. Moura').attributes
|
316
321
|
end
|
317
322
|
end
|
318
323
|
|
@@ -429,25 +434,53 @@ module ActiveModelSerializers
|
|
429
434
|
end
|
430
435
|
|
431
436
|
def test_fragment_fetch_with_virtual_attributes
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
+
author = Author.new(name: 'Joao M. D. Moura')
|
438
|
+
role = Role.new(name: 'Great Author', description: nil)
|
439
|
+
role.author = [author]
|
440
|
+
role_serializer = RoleSerializer.new(role)
|
441
|
+
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(role_serializer)
|
442
|
+
expected_result = {
|
443
|
+
id: role.id,
|
444
|
+
description: role.description,
|
445
|
+
slug: "#{role.name}-#{role.id}",
|
446
|
+
name: role.name
|
447
|
+
}
|
448
|
+
cache_store.clear
|
449
|
+
|
450
|
+
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|
451
|
+
assert_equal(role_hash, expected_result)
|
437
452
|
|
453
|
+
role.attributes[:id] = 'this has been updated'
|
454
|
+
role.name = 'this was cached'
|
455
|
+
|
456
|
+
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|
457
|
+
assert_equal(expected_result.merge(id: role.id), role_hash)
|
458
|
+
end
|
459
|
+
|
460
|
+
def test_fragment_fetch_with_except
|
461
|
+
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(@bio_serializer)
|
438
462
|
expected_result = {
|
439
|
-
id: @
|
440
|
-
|
441
|
-
|
442
|
-
name: @role.name
|
463
|
+
id: @bio.id,
|
464
|
+
rating: nil,
|
465
|
+
content: @bio.content
|
443
466
|
}
|
444
|
-
|
467
|
+
cache_store.clear
|
468
|
+
|
469
|
+
bio_hash = @bio_serializer.fetch_attributes_fragment(adapter_instance)
|
470
|
+
assert_equal(expected_result, bio_hash)
|
471
|
+
|
472
|
+
@bio.content = 'this has been updated'
|
473
|
+
@bio.rating = 'this was cached'
|
474
|
+
|
475
|
+
bio_hash = @bio_serializer.fetch_attributes_fragment(adapter_instance)
|
476
|
+
assert_equal(expected_result.merge(content: @bio.content), bio_hash)
|
445
477
|
end
|
446
478
|
|
447
479
|
def test_fragment_fetch_with_namespaced_object
|
448
480
|
@spam = Spam::UnrelatedLink.new(id: 'spam-id-1')
|
449
481
|
@spam_serializer = Spam::UnrelatedLinkSerializer.new(@spam)
|
450
|
-
|
482
|
+
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(@spam_serializer)
|
483
|
+
@spam_hash = @spam_serializer.fetch_attributes_fragment(adapter_instance)
|
451
484
|
expected_result = {
|
452
485
|
id: @spam.id
|
453
486
|
}
|
@@ -476,10 +509,5 @@ module ActiveModelSerializers
|
|
476
509
|
def adapter
|
477
510
|
@serializable_resource.adapter
|
478
511
|
end
|
479
|
-
|
480
|
-
def cached_serialization(serializer)
|
481
|
-
cache_key = serializer.cache_key(adapter)
|
482
|
-
cache_store.fetch(cache_key)
|
483
|
-
end
|
484
512
|
end
|
485
513
|
end
|