active_model_serializers 0.10.0 → 0.10.1
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/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
|