active_model_serializers 0.10.0 → 0.10.3
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/.rubocop.yml +2 -4
- data/.travis.yml +9 -1
- data/CHANGELOG.md +81 -2
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +5 -2
- data/README.md +24 -24
- data/Rakefile +3 -3
- data/active_model_serializers.gemspec +20 -24
- data/docs/ARCHITECTURE.md +6 -7
- data/docs/README.md +2 -0
- data/docs/general/adapters.md +4 -2
- data/docs/general/caching.md +7 -1
- data/docs/general/configuration_options.md +70 -1
- data/docs/general/deserialization.md +1 -1
- data/docs/general/fields.md +31 -0
- data/docs/general/rendering.md +42 -3
- data/docs/general/serializers.md +97 -8
- data/docs/howto/add_pagination_links.md +4 -5
- data/docs/howto/add_relationship_links.md +137 -0
- data/docs/howto/add_root_key.md +4 -0
- data/docs/howto/grape_integration.md +42 -0
- data/docs/howto/outside_controller_use.md +9 -2
- data/docs/howto/passing_arbitrary_options.md +2 -2
- data/docs/howto/test.md +2 -0
- data/docs/howto/upgrade_from_0_8_to_0_10.md +265 -0
- data/docs/integrations/ember-and-json-api.md +64 -32
- data/docs/jsonapi/schema.md +1 -1
- data/lib/action_controller/serialization.rb +13 -3
- data/lib/active_model/serializer/adapter/base.rb +2 -0
- data/lib/active_model/serializer/array_serializer.rb +8 -5
- data/lib/active_model/serializer/association.rb +19 -4
- data/lib/active_model/serializer/belongs_to_reflection.rb +0 -3
- data/lib/active_model/serializer/collection_serializer.rb +35 -12
- data/lib/active_model/serializer/{associations.rb → concerns/associations.rb} +13 -11
- data/lib/active_model/serializer/{attributes.rb → concerns/attributes.rb} +0 -0
- data/lib/active_model/serializer/{caching.rb → concerns/caching.rb} +72 -113
- data/lib/active_model/serializer/{configuration.rb → concerns/configuration.rb} +25 -1
- data/lib/active_model/serializer/{links.rb → concerns/links.rb} +0 -0
- data/lib/active_model/serializer/{meta.rb → concerns/meta.rb} +0 -0
- data/lib/active_model/serializer/{type.rb → concerns/type.rb} +0 -0
- data/lib/active_model/serializer/error_serializer.rb +11 -7
- data/lib/active_model/serializer/errors_serializer.rb +25 -20
- 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/lint.rb +134 -130
- data/lib/active_model/serializer/reflection.rb +37 -21
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model/serializer.rb +76 -37
- data/lib/active_model_serializers/adapter/attributes.rb +3 -66
- data/lib/active_model_serializers/adapter/base.rb +38 -38
- 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/adapter/json_api/relationship.rb +30 -19
- data/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +23 -9
- data/lib/active_model_serializers/adapter/json_api.rb +44 -43
- data/lib/active_model_serializers/adapter.rb +6 -0
- data/lib/active_model_serializers/deprecate.rb +1 -2
- data/lib/active_model_serializers/deserialization.rb +2 -0
- data/lib/active_model_serializers/key_transform.rb +4 -0
- data/lib/active_model_serializers/lookup_chain.rb +80 -0
- data/lib/active_model_serializers/model.rb +4 -2
- data/lib/active_model_serializers/railtie.rb +3 -1
- data/lib/active_model_serializers/register_jsonapi_renderer.rb +44 -31
- data/lib/active_model_serializers/serializable_resource.rb +6 -5
- data/lib/active_model_serializers/serialization_context.rb +10 -3
- data/lib/active_model_serializers.rb +7 -0
- data/lib/generators/rails/serializer_generator.rb +4 -4
- data/lib/grape/active_model_serializers.rb +7 -5
- 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 +4 -4
- 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 +6 -7
- data/test/action_controller/json_api/fields_test.rb +57 -0
- data/test/action_controller/json_api/linked_test.rb +29 -24
- data/test/action_controller/json_api/pagination_test.rb +19 -19
- data/test/action_controller/json_api/transform_test.rb +3 -3
- data/test/action_controller/lookup_proc_test.rb +49 -0
- data/test/action_controller/namespace_lookup_test.rb +226 -0
- data/test/action_controller/serialization_test.rb +10 -7
- data/test/active_model_serializers/json_pointer_test.rb +15 -13
- data/test/active_model_serializers/key_transform_test.rb +286 -252
- data/test/active_model_serializers/model_test.rb +17 -4
- 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/attributes_test.rb +43 -0
- data/test/adapter/json/collection_test.rb +14 -0
- data/test/adapter/json/transform_test.rb +15 -15
- data/test/adapter/json_api/collection_test.rb +4 -3
- data/test/adapter/json_api/errors_test.rb +17 -19
- data/test/adapter/json_api/fields_test.rb +4 -3
- data/test/adapter/json_api/has_many_test.rb +39 -18
- data/test/adapter/json_api/include_data_if_sideloaded_test.rb +166 -0
- data/test/adapter/json_api/json_api_test.rb +5 -7
- data/test/adapter/json_api/linked_test.rb +33 -12
- data/test/adapter/json_api/links_test.rb +4 -2
- data/test/adapter/json_api/pagination_links_test.rb +35 -8
- data/test/adapter/json_api/relationship_test.rb +309 -73
- data/test/adapter/json_api/resource_identifier_test.rb +27 -2
- data/test/adapter/json_api/resource_meta_test.rb +3 -3
- data/test/adapter/json_api/transform_test.rb +255 -253
- data/test/adapter/json_api/type_test.rb +1 -1
- data/test/adapter/json_test.rb +8 -7
- data/test/adapter/null_test.rb +1 -2
- data/test/adapter/polymorphic_test.rb +5 -5
- data/test/adapter_test.rb +1 -1
- data/test/benchmark/app.rb +1 -1
- data/test/benchmark/benchmarking_support.rb +1 -1
- data/test/benchmark/bm_active_record.rb +81 -0
- data/test/benchmark/bm_adapter.rb +38 -0
- data/test/benchmark/bm_caching.rb +16 -16
- data/test/benchmark/bm_lookup_chain.rb +83 -0
- 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 +143 -49
- data/test/collection_serializer_test.rb +3 -3
- data/test/fixtures/poro.rb +52 -48
- data/test/generators/serializer_generator_test.rb +22 -5
- data/test/grape_test.rb +152 -56
- data/test/lint_test.rb +1 -1
- data/test/logger_test.rb +13 -11
- data/test/serializable_resource_test.rb +18 -22
- data/test/serializers/association_macros_test.rb +3 -2
- data/test/serializers/associations_test.rb +107 -32
- data/test/serializers/attribute_test.rb +2 -2
- data/test/serializers/attributes_test.rb +1 -1
- data/test/serializers/fieldset_test.rb +1 -1
- data/test/serializers/meta_test.rb +12 -6
- data/test/serializers/root_test.rb +1 -1
- data/test/serializers/serializer_for_test.rb +6 -4
- data/test/serializers/serializer_for_with_namespace_test.rb +87 -0
- data/test/support/isolated_unit.rb +5 -2
- data/test/support/rails5_shims.rb +8 -2
- data/test/support/rails_app.rb +0 -9
- data/test/support/serialization_testing.rb +23 -5
- data/test/test_helper.rb +1 -0
- metadata +85 -34
- data/.rubocop_todo.yml +0 -167
- data/lib/active_model/serializer/include_tree.rb +0 -111
- data/test/adapter/json_api/relationships_test.rb +0 -199
- 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/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
@@ -4,22 +4,46 @@ require 'tempfile'
|
|
4
4
|
|
5
5
|
module ActiveModelSerializers
|
6
6
|
class CacheTest < ActiveSupport::TestCase
|
7
|
-
|
7
|
+
# Instead of a primitive cache key (i.e. a string), this class
|
8
|
+
# returns a list of objects that require to be expanded themselves.
|
9
|
+
class AuthorWithExpandableCacheElements < Author
|
10
|
+
# For the test purposes it's important that #to_s for HasCacheKey differs
|
11
|
+
# between instances, hence not a Struct.
|
12
|
+
class HasCacheKey
|
13
|
+
attr_reader :cache_key
|
14
|
+
def initialize(cache_key)
|
15
|
+
@cache_key = cache_key
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"HasCacheKey##{object_id}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def cache_key
|
24
|
+
[
|
25
|
+
HasCacheKey.new(name),
|
26
|
+
HasCacheKey.new(id)
|
27
|
+
]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class UncachedAuthor < Author
|
8
32
|
# To confirm cache_key is set using updated_at and cache_key option passed to cache
|
9
33
|
undef_method :cache_key
|
10
34
|
end
|
11
35
|
|
12
|
-
Article
|
36
|
+
class Article < ::Model
|
13
37
|
# To confirm error is raised when cache_key is not set and cache_key option not passed to cache
|
14
38
|
undef_method :cache_key
|
15
39
|
end
|
16
40
|
|
17
|
-
ArticleSerializer
|
41
|
+
class ArticleSerializer < ActiveModel::Serializer
|
18
42
|
cache only: [:place], skip_digest: true
|
19
43
|
attributes :title
|
20
44
|
end
|
21
45
|
|
22
|
-
InheritedRoleSerializer
|
46
|
+
class InheritedRoleSerializer < RoleSerializer
|
23
47
|
cache key: 'inherited_role', only: [:name, :special_attribute]
|
24
48
|
attribute :special_attribute
|
25
49
|
end
|
@@ -101,14 +125,28 @@ module ActiveModelSerializers
|
|
101
125
|
uncached_author_serializer = AuthorSerializer.new(uncached_author)
|
102
126
|
|
103
127
|
render_object_with_cache(uncached_author)
|
104
|
-
key = "#{uncached_author_serializer.class._cache_key}/#{uncached_author_serializer.object.id}-#{uncached_author_serializer.object.updated_at.strftime(
|
105
|
-
key = "#{key}/#{adapter.
|
128
|
+
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')}"
|
129
|
+
key = "#{key}/#{adapter.cache_key}"
|
106
130
|
assert_equal(uncached_author_serializer.attributes.to_json, cache_store.fetch(key).to_json)
|
107
131
|
end
|
108
132
|
|
133
|
+
def test_cache_key_expansion
|
134
|
+
author = AuthorWithExpandableCacheElements.new(id: 10, name: 'hello')
|
135
|
+
same_author = AuthorWithExpandableCacheElements.new(id: 10, name: 'hello')
|
136
|
+
diff_author = AuthorWithExpandableCacheElements.new(id: 11, name: 'hello')
|
137
|
+
|
138
|
+
author_serializer = AuthorSerializer.new(author)
|
139
|
+
same_author_serializer = AuthorSerializer.new(same_author)
|
140
|
+
diff_author_serializer = AuthorSerializer.new(diff_author)
|
141
|
+
adapter = AuthorSerializer.serialization_adapter_instance
|
142
|
+
|
143
|
+
assert_equal(author_serializer.cache_key(adapter), same_author_serializer.cache_key(adapter))
|
144
|
+
refute_equal(author_serializer.cache_key(adapter), diff_author_serializer.cache_key(adapter))
|
145
|
+
end
|
146
|
+
|
109
147
|
def test_default_cache_key_fallback
|
110
148
|
render_object_with_cache(@comment)
|
111
|
-
key = "#{@comment.cache_key}/#{adapter.
|
149
|
+
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
112
150
|
assert_equal(@comment_serializer.attributes.to_json, cache_store.fetch(key).to_json)
|
113
151
|
end
|
114
152
|
|
@@ -117,7 +155,7 @@ module ActiveModelSerializers
|
|
117
155
|
e = assert_raises ActiveModel::Serializer::UndefinedCacheKey do
|
118
156
|
render_object_with_cache(article)
|
119
157
|
end
|
120
|
-
assert_match(/ActiveModelSerializers::CacheTest::Article must define #cache_key, or the 'key:' option must be passed into '
|
158
|
+
assert_match(/ActiveModelSerializers::CacheTest::Article must define #cache_key, or the 'key:' option must be passed into 'ActiveModelSerializers::CacheTest::ArticleSerializer.cache'/, e.message)
|
121
159
|
end
|
122
160
|
|
123
161
|
def test_cache_options_definition
|
@@ -127,7 +165,7 @@ module ActiveModelSerializers
|
|
127
165
|
end
|
128
166
|
|
129
167
|
def test_fragment_cache_definition
|
130
|
-
assert_equal([:name], @role_serializer.class._cache_only)
|
168
|
+
assert_equal([:name, :slug], @role_serializer.class._cache_only)
|
131
169
|
assert_equal([:content], @bio_serializer.class._cache_except)
|
132
170
|
end
|
133
171
|
|
@@ -139,9 +177,9 @@ module ActiveModelSerializers
|
|
139
177
|
Timecop.freeze(Time.current) do
|
140
178
|
render_object_with_cache(@post)
|
141
179
|
|
142
|
-
key = "#{@post.cache_key}/#{adapter.
|
180
|
+
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
143
181
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
144
|
-
key = "#{@comment.cache_key}/#{adapter.
|
182
|
+
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
145
183
|
assert_equal(@comment_serializer.attributes, cache_store.fetch(key))
|
146
184
|
end
|
147
185
|
end
|
@@ -152,9 +190,9 @@ module ActiveModelSerializers
|
|
152
190
|
render_object_with_cache(@post)
|
153
191
|
|
154
192
|
# Check if it cached the objects separately
|
155
|
-
key = "#{@post.cache_key}/#{adapter.
|
193
|
+
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
156
194
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
157
|
-
key = "#{@comment.cache_key}/#{adapter.
|
195
|
+
key = "#{@comment.cache_key}/#{adapter.cache_key}"
|
158
196
|
assert_equal(@comment_serializer.attributes, cache_store.fetch(key))
|
159
197
|
|
160
198
|
# Simulating update on comments relationship with Post
|
@@ -166,9 +204,9 @@ module ActiveModelSerializers
|
|
166
204
|
render_object_with_cache(@post)
|
167
205
|
|
168
206
|
# Check if the the new comment was cached
|
169
|
-
key = "#{new_comment.cache_key}/#{adapter.
|
207
|
+
key = "#{new_comment.cache_key}/#{adapter.cache_key}"
|
170
208
|
assert_equal(new_comment_serializer.attributes, cache_store.fetch(key))
|
171
|
-
key = "#{@post.cache_key}/#{adapter.
|
209
|
+
key = "#{@post.cache_key}/#{adapter.cache_key}"
|
172
210
|
assert_equal(@post_serializer.attributes, cache_store.fetch(key))
|
173
211
|
end
|
174
212
|
end
|
@@ -178,14 +216,14 @@ module ActiveModelSerializers
|
|
178
216
|
id: @location.id,
|
179
217
|
lat: @location.lat,
|
180
218
|
lng: @location.lng,
|
181
|
-
|
219
|
+
address: 'Nowhere'
|
182
220
|
}
|
183
221
|
|
184
222
|
hash = render_object_with_cache(@location)
|
185
223
|
|
186
224
|
assert_equal(hash, expected_result)
|
187
|
-
key = "#{@location.cache_key}/#{adapter.
|
188
|
-
assert_equal({
|
225
|
+
key = "#{@location.cache_key}/#{adapter.cache_key}"
|
226
|
+
assert_equal({ address: 'Nowhere' }, cache_store.fetch(key))
|
189
227
|
end
|
190
228
|
|
191
229
|
def test_fragment_cache_with_inheritance
|
@@ -204,7 +242,7 @@ module ActiveModelSerializers
|
|
204
242
|
|
205
243
|
# Based on original failing test by @kevintyll
|
206
244
|
# rubocop:disable Metrics/AbcSize
|
207
|
-
def
|
245
|
+
def test_a_serializer_rendered_by_two_adapter_returns_differently_fetch_attributes
|
208
246
|
Object.const_set(:Alert, Class.new(ActiveModelSerializers::Model) do
|
209
247
|
attr_accessor :id, :status, :resource, :started_at, :ended_at, :updated_at, :created_at
|
210
248
|
end)
|
@@ -225,7 +263,7 @@ module ActiveModelSerializers
|
|
225
263
|
created_at: Time.new(2016, 3, 31, 21, 37, 35, 0)
|
226
264
|
)
|
227
265
|
|
228
|
-
|
266
|
+
expected_fetch_attributes = {
|
229
267
|
id: 1,
|
230
268
|
status: 'fail',
|
231
269
|
resource: 'resource-1',
|
@@ -250,7 +288,7 @@ module ActiveModelSerializers
|
|
250
288
|
# Assert attributes are serialized correctly
|
251
289
|
serializable_alert = serializable(alert, serializer: AlertSerializer, adapter: :attributes)
|
252
290
|
attributes_serialization = serializable_alert.as_json
|
253
|
-
assert_equal
|
291
|
+
assert_equal expected_fetch_attributes, alert.attributes
|
254
292
|
assert_equal alert.attributes, attributes_serialization
|
255
293
|
attributes_cache_key = serializable_alert.adapter.serializer.cache_key(serializable_alert.adapter)
|
256
294
|
assert_equal attributes_serialization, cache_store.fetch(attributes_cache_key)
|
@@ -276,7 +314,7 @@ module ActiveModelSerializers
|
|
276
314
|
|
277
315
|
def test_uses_file_digest_in_cache_key
|
278
316
|
render_object_with_cache(@blog)
|
279
|
-
key = "#{@blog.cache_key}/#{adapter.
|
317
|
+
key = "#{@blog.cache_key}/#{adapter.cache_key}/#{::Model::FILE_DIGEST}"
|
280
318
|
assert_equal(@blog_serializer.attributes, cache_store.fetch(key))
|
281
319
|
end
|
282
320
|
|
@@ -286,33 +324,66 @@ module ActiveModelSerializers
|
|
286
324
|
|
287
325
|
def test_object_cache_keys
|
288
326
|
serializable = ActiveModelSerializers::SerializableResource.new([@comment, @comment])
|
289
|
-
|
327
|
+
include_directive = JSONAPI::IncludeDirective.new('*', allow_wildcard: true)
|
290
328
|
|
291
|
-
actual = ActiveModel::Serializer.object_cache_keys(serializable.adapter.serializer, serializable.adapter,
|
329
|
+
actual = ActiveModel::Serializer.object_cache_keys(serializable.adapter.serializer, serializable.adapter, include_directive)
|
292
330
|
|
293
331
|
assert_equal 3, actual.size
|
294
|
-
assert actual.any? { |key| key == "comment/1/#{serializable.adapter.
|
332
|
+
assert actual.any? { |key| key == "comment/1/#{serializable.adapter.cache_key}" }
|
295
333
|
assert actual.any? { |key| key =~ %r{post/post-\d+} }
|
296
334
|
assert actual.any? { |key| key =~ %r{author/author-\d+} }
|
297
335
|
end
|
298
336
|
|
299
|
-
def
|
300
|
-
|
337
|
+
def test_fetch_attributes_from_cache
|
338
|
+
serializers = ActiveModel::Serializer::CollectionSerializer.new([@comment, @comment])
|
301
339
|
|
302
340
|
Timecop.freeze(Time.current) do
|
303
341
|
render_object_with_cache(@comment)
|
304
342
|
|
305
|
-
|
306
|
-
|
307
|
-
|
343
|
+
options = {}
|
344
|
+
adapter_options = {}
|
345
|
+
adapter_instance = ActiveModelSerializers::Adapter::Attributes.new(serializers, adapter_options)
|
346
|
+
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
347
|
+
cached_attributes = adapter_options.fetch(:cached_attributes)
|
348
|
+
|
349
|
+
include_directive = ActiveModelSerializers.default_include_directive
|
350
|
+
manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive)
|
351
|
+
assert_equal manual_cached_attributes, cached_attributes
|
308
352
|
|
309
|
-
assert_equal cached_attributes["#{@comment.cache_key}/#{
|
310
|
-
assert_equal cached_attributes["#{@comment.post.cache_key}/#{
|
353
|
+
assert_equal cached_attributes["#{@comment.cache_key}/#{adapter_instance.cache_key}"], Comment.new(id: 1, body: 'ZOMG A COMMENT').attributes
|
354
|
+
assert_equal cached_attributes["#{@comment.post.cache_key}/#{adapter_instance.cache_key}"], Post.new(id: 'post', title: 'New Post', body: 'Body').attributes
|
311
355
|
|
312
356
|
writer = @comment.post.blog.writer
|
313
357
|
writer_cache_key = writer.cache_key
|
358
|
+
assert_equal cached_attributes["#{writer_cache_key}/#{adapter_instance.cache_key}"], Author.new(id: 'author', name: 'Joao M. D. Moura').attributes
|
359
|
+
end
|
360
|
+
end
|
314
361
|
|
315
|
-
|
362
|
+
def test_cache_read_multi_with_fragment_cache_enabled
|
363
|
+
post_serializer = Class.new(ActiveModel::Serializer) do
|
364
|
+
cache except: [:body]
|
365
|
+
end
|
366
|
+
|
367
|
+
serializers = ActiveModel::Serializer::CollectionSerializer.new([@post, @post], serializer: post_serializer)
|
368
|
+
|
369
|
+
Timecop.freeze(Time.current) do
|
370
|
+
# Warming up.
|
371
|
+
options = {}
|
372
|
+
adapter_options = {}
|
373
|
+
adapter_instance = ActiveModelSerializers::Adapter::Attributes.new(serializers, adapter_options)
|
374
|
+
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
375
|
+
|
376
|
+
# Should find something with read_multi now
|
377
|
+
adapter_options = {}
|
378
|
+
serializers.serializable_hash(adapter_options, options, adapter_instance)
|
379
|
+
cached_attributes = adapter_options.fetch(:cached_attributes)
|
380
|
+
|
381
|
+
include_directive = ActiveModelSerializers.default_include_directive
|
382
|
+
manual_cached_attributes = ActiveModel::Serializer.cache_read_multi(serializers, adapter_instance, include_directive)
|
383
|
+
|
384
|
+
refute_equal 0, cached_attributes.size
|
385
|
+
refute_equal 0, manual_cached_attributes.size
|
386
|
+
assert_equal manual_cached_attributes, cached_attributes
|
316
387
|
end
|
317
388
|
end
|
318
389
|
|
@@ -429,25 +500,53 @@ module ActiveModelSerializers
|
|
429
500
|
end
|
430
501
|
|
431
502
|
def test_fragment_fetch_with_virtual_attributes
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
503
|
+
author = Author.new(name: 'Joao M. D. Moura')
|
504
|
+
role = Role.new(name: 'Great Author', description: nil)
|
505
|
+
role.author = [author]
|
506
|
+
role_serializer = RoleSerializer.new(role)
|
507
|
+
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(role_serializer)
|
508
|
+
expected_result = {
|
509
|
+
id: role.id,
|
510
|
+
description: role.description,
|
511
|
+
slug: "#{role.name}-#{role.id}",
|
512
|
+
name: role.name
|
513
|
+
}
|
514
|
+
cache_store.clear
|
515
|
+
|
516
|
+
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|
517
|
+
assert_equal(role_hash, expected_result)
|
518
|
+
|
519
|
+
role.attributes[:id] = 'this has been updated'
|
520
|
+
role.name = 'this was cached'
|
521
|
+
|
522
|
+
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|
523
|
+
assert_equal(expected_result.merge(id: role.id), role_hash)
|
524
|
+
end
|
437
525
|
|
526
|
+
def test_fragment_fetch_with_except
|
527
|
+
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(@bio_serializer)
|
438
528
|
expected_result = {
|
439
|
-
id: @
|
440
|
-
|
441
|
-
|
442
|
-
name: @role.name
|
529
|
+
id: @bio.id,
|
530
|
+
rating: nil,
|
531
|
+
content: @bio.content
|
443
532
|
}
|
444
|
-
|
533
|
+
cache_store.clear
|
534
|
+
|
535
|
+
bio_hash = @bio_serializer.fetch_attributes_fragment(adapter_instance)
|
536
|
+
assert_equal(expected_result, bio_hash)
|
537
|
+
|
538
|
+
@bio.content = 'this has been updated'
|
539
|
+
@bio.rating = 'this was cached'
|
540
|
+
|
541
|
+
bio_hash = @bio_serializer.fetch_attributes_fragment(adapter_instance)
|
542
|
+
assert_equal(expected_result.merge(content: @bio.content), bio_hash)
|
445
543
|
end
|
446
544
|
|
447
545
|
def test_fragment_fetch_with_namespaced_object
|
448
546
|
@spam = Spam::UnrelatedLink.new(id: 'spam-id-1')
|
449
547
|
@spam_serializer = Spam::UnrelatedLinkSerializer.new(@spam)
|
450
|
-
|
548
|
+
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(@spam_serializer)
|
549
|
+
@spam_hash = @spam_serializer.fetch_attributes_fragment(adapter_instance)
|
451
550
|
expected_result = {
|
452
551
|
id: @spam.id
|
453
552
|
}
|
@@ -476,10 +575,5 @@ module ActiveModelSerializers
|
|
476
575
|
def adapter
|
477
576
|
@serializable_resource.adapter
|
478
577
|
end
|
479
|
-
|
480
|
-
def cached_serialization(serializer)
|
481
|
-
cache_key = serializer.cache_key(adapter)
|
482
|
-
cache_store.fetch(cache_key)
|
483
|
-
end
|
484
578
|
end
|
485
579
|
end
|
@@ -3,7 +3,7 @@ require 'test_helper'
|
|
3
3
|
module ActiveModel
|
4
4
|
class Serializer
|
5
5
|
class CollectionSerializerTest < ActiveSupport::TestCase
|
6
|
-
MessagesSerializer
|
6
|
+
class MessagesSerializer < ActiveModel::Serializer
|
7
7
|
type 'messages'
|
8
8
|
end
|
9
9
|
|
@@ -11,7 +11,7 @@ module ActiveModel
|
|
11
11
|
@comment = Comment.new
|
12
12
|
@post = Post.new
|
13
13
|
@resource = build_named_collection @comment, @post
|
14
|
-
@serializer = collection_serializer.new(@resource,
|
14
|
+
@serializer = collection_serializer.new(@resource, some: :options)
|
15
15
|
end
|
16
16
|
|
17
17
|
def collection_serializer
|
@@ -44,7 +44,7 @@ module ActiveModel
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def test_serializer_option_not_passed_to_each_serializer
|
47
|
-
serializers = collection_serializer.new([@post],
|
47
|
+
serializers = collection_serializer.new([@post], serializer: PostSerializer).to_a
|
48
48
|
|
49
49
|
refute serializers.first.custom_options.key?(:serializer)
|
50
50
|
end
|