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
@@ -7,10 +7,9 @@ module ActiveModel
|
|
7
7
|
included do
|
8
8
|
with_options instance_writer: false, instance_reader: false do |serializer|
|
9
9
|
serializer.class_attribute :_cache # @api private : the cache store
|
10
|
-
serializer.class_attribute :_fragmented # @api private : @see ::fragmented
|
11
10
|
serializer.class_attribute :_cache_key # @api private : when present, is first item in cache_key. Ignored if the serializable object defines #cache_key.
|
12
|
-
serializer.class_attribute :_cache_only # @api private : when fragment caching, whitelists
|
13
|
-
serializer.class_attribute :_cache_except # @api private : when fragment caching, blacklists
|
11
|
+
serializer.class_attribute :_cache_only # @api private : when fragment caching, whitelists fetch_attributes. Cannot combine with except
|
12
|
+
serializer.class_attribute :_cache_except # @api private : when fragment caching, blacklists fetch_attributes. Cannot combine with only
|
14
13
|
serializer.class_attribute :_cache_options # @api private : used by CachedSerializer, passed to _cache.fetch
|
15
14
|
# _cache_options include:
|
16
15
|
# expires_in
|
@@ -19,7 +18,7 @@ module ActiveModel
|
|
19
18
|
# race_condition_ttl
|
20
19
|
# Passed to ::_cache as
|
21
20
|
# serializer.cache_store.fetch(cache_key, @klass._cache_options)
|
22
|
-
# Passed as second argument to serializer.cache_store.fetch(cache_key,
|
21
|
+
# Passed as second argument to serializer.cache_store.fetch(cache_key, serializer_class._cache_options)
|
23
22
|
serializer.class_attribute :_cache_digest_file_path # @api private : Derived at inheritance
|
24
23
|
end
|
25
24
|
end
|
@@ -69,19 +68,15 @@ module ActiveModel
|
|
69
68
|
_cache_options && _cache_options[:skip_digest]
|
70
69
|
end
|
71
70
|
|
72
|
-
def
|
73
|
-
_cache_only ? _cache_only : _attributes - _cache_except
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
# Used by FragmentCache on the CachedSerializer
|
82
|
-
# to call attribute methods on the fragmented cached serializer.
|
83
|
-
def fragmented(serializer)
|
84
|
-
self._fragmented = serializer
|
71
|
+
def fragmented_attributes
|
72
|
+
cached = _cache_only ? _cache_only : _attributes - _cache_except
|
73
|
+
cached = cached.map! { |field| _attributes_keys.fetch(field, field) }
|
74
|
+
non_cached = _attributes - cached
|
75
|
+
non_cached = non_cached.map! { |field| _attributes_keys.fetch(field, field) }
|
76
|
+
{
|
77
|
+
cached: cached,
|
78
|
+
non_cached: non_cached
|
79
|
+
}
|
85
80
|
end
|
86
81
|
|
87
82
|
# Enables a serializer to be automatically cached
|
@@ -163,10 +158,10 @@ module ActiveModel
|
|
163
158
|
|
164
159
|
# Read cache from cache_store
|
165
160
|
# @return [Hash]
|
166
|
-
def cache_read_multi(collection_serializer, adapter_instance,
|
161
|
+
def cache_read_multi(collection_serializer, adapter_instance, include_directive)
|
167
162
|
return {} if ActiveModelSerializers.config.cache_store.blank?
|
168
163
|
|
169
|
-
keys = object_cache_keys(collection_serializer, adapter_instance,
|
164
|
+
keys = object_cache_keys(collection_serializer, adapter_instance, include_directive)
|
170
165
|
|
171
166
|
return {} if keys.blank?
|
172
167
|
|
@@ -176,15 +171,15 @@ module ActiveModel
|
|
176
171
|
# Find all cache_key for the collection_serializer
|
177
172
|
# @param serializers [ActiveModel::Serializer::CollectionSerializer]
|
178
173
|
# @param adapter_instance [ActiveModelSerializers::Adapter::Base]
|
179
|
-
# @param
|
174
|
+
# @param include_directive [JSONAPI::IncludeDirective]
|
180
175
|
# @return [Array] all cache_key of collection_serializer
|
181
|
-
def object_cache_keys(collection_serializer, adapter_instance,
|
176
|
+
def object_cache_keys(collection_serializer, adapter_instance, include_directive)
|
182
177
|
cache_keys = []
|
183
178
|
|
184
179
|
collection_serializer.each do |serializer|
|
185
180
|
cache_keys << object_cache_key(serializer, adapter_instance)
|
186
181
|
|
187
|
-
serializer.associations(
|
182
|
+
serializer.associations(include_directive).each do |association|
|
188
183
|
if association.serializer.respond_to?(:each)
|
189
184
|
association.serializer.each do |sub_serializer|
|
190
185
|
cache_keys << object_cache_key(sub_serializer, adapter_instance)
|
@@ -206,112 +201,65 @@ module ActiveModel
|
|
206
201
|
end
|
207
202
|
end
|
208
203
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
204
|
+
### INSTANCE METHODS
|
205
|
+
def fetch_attributes(fields, cached_attributes, adapter_instance)
|
206
|
+
if serializer_class.cache_enabled?
|
207
|
+
key = cache_key(adapter_instance)
|
208
|
+
cached_attributes.fetch(key) do
|
209
|
+
serializer_class.cache_store.fetch(key, serializer_class._cache_options) do
|
210
|
+
attributes(fields, true)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
elsif serializer_class.fragment_cache_enabled?
|
214
|
+
fetch_attributes_fragment(adapter_instance)
|
215
|
+
else
|
216
|
+
attributes(fields, true)
|
215
217
|
end
|
216
218
|
end
|
217
219
|
|
218
|
-
def
|
219
|
-
if
|
220
|
-
|
220
|
+
def fetch(adapter_instance, cache_options = serializer_class._cache_options)
|
221
|
+
if serializer_class.cache_store
|
222
|
+
serializer_class.cache_store.fetch(cache_key(adapter_instance), cache_options) do
|
221
223
|
yield
|
222
224
|
end
|
223
|
-
elsif self.class.fragment_cache_enabled?
|
224
|
-
fetch_fragment_cache(adapter_instance)
|
225
225
|
else
|
226
226
|
yield
|
227
227
|
end
|
228
228
|
end
|
229
229
|
|
230
|
-
# 1.
|
231
|
-
# 2.
|
232
|
-
# 3.
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
# NonCachedUser_AdminSerializer
|
252
|
-
#
|
253
|
-
# Given a hash of its cached and non-cached serializers
|
254
|
-
# 1. Determine cached attributes from serializer class options
|
255
|
-
# 2. Add cached attributes to cached Serializer
|
256
|
-
# 3. Add non-cached attributes to non-cached Serializer
|
257
|
-
def fetch_fragment_cache(adapter_instance)
|
258
|
-
serializer_class_name = self.class.name.gsub('::'.freeze, '_'.freeze)
|
259
|
-
self.class._cache_options ||= {}
|
260
|
-
self.class._cache_options[:key] = self.class._cache_key if self.class._cache_key
|
261
|
-
|
262
|
-
cached_serializer = _get_or_create_fragment_cached_serializer(serializer_class_name)
|
263
|
-
cached_hash = ActiveModelSerializers::SerializableResource.new(
|
264
|
-
object,
|
265
|
-
serializer: cached_serializer,
|
266
|
-
adapter: adapter_instance.class
|
267
|
-
).serializable_hash
|
268
|
-
|
269
|
-
non_cached_serializer = _get_or_create_fragment_non_cached_serializer(serializer_class_name)
|
270
|
-
non_cached_hash = ActiveModelSerializers::SerializableResource.new(
|
271
|
-
object,
|
272
|
-
serializer: non_cached_serializer,
|
273
|
-
adapter: adapter_instance.class
|
274
|
-
).serializable_hash
|
230
|
+
# 1. Determine cached fields from serializer class options
|
231
|
+
# 2. Get non_cached_fields and fetch cache_fields
|
232
|
+
# 3. Merge the two hashes using adapter_instance#fragment_cache
|
233
|
+
def fetch_attributes_fragment(adapter_instance)
|
234
|
+
serializer_class._cache_options ||= {}
|
235
|
+
serializer_class._cache_options[:key] = serializer_class._cache_key if serializer_class._cache_key
|
236
|
+
fields = serializer_class.fragmented_attributes
|
237
|
+
|
238
|
+
non_cached_fields = fields[:non_cached].dup
|
239
|
+
non_cached_hash = attributes(non_cached_fields, true)
|
240
|
+
include_directive = JSONAPI::IncludeDirective.new(non_cached_fields - non_cached_hash.keys)
|
241
|
+
non_cached_hash.merge! resource_relationships({}, { include_directive: include_directive }, adapter_instance)
|
242
|
+
|
243
|
+
cached_fields = fields[:cached].dup
|
244
|
+
key = cache_key(adapter_instance)
|
245
|
+
cached_hash =
|
246
|
+
serializer_class.cache_store.fetch(key, serializer_class._cache_options) do
|
247
|
+
hash = attributes(cached_fields, true)
|
248
|
+
include_directive = JSONAPI::IncludeDirective.new(cached_fields - hash.keys)
|
249
|
+
hash.merge! resource_relationships({}, { include_directive: include_directive }, adapter_instance)
|
250
|
+
end
|
275
251
|
|
276
252
|
# Merge both results
|
277
253
|
adapter_instance.fragment_cache(cached_hash, non_cached_hash)
|
278
254
|
end
|
279
255
|
|
280
|
-
def _get_or_create_fragment_cached_serializer(serializer_class_name)
|
281
|
-
cached_serializer = _get_or_create_fragment_serializer "Cached#{serializer_class_name}"
|
282
|
-
cached_serializer.cache(self.class._cache_options)
|
283
|
-
cached_serializer.type(self.class._type)
|
284
|
-
cached_serializer.fragmented(self)
|
285
|
-
self.class.cached_attributes.each do |attribute|
|
286
|
-
options = self.class._attributes_keys[attribute] || {}
|
287
|
-
cached_serializer.attribute(attribute, options)
|
288
|
-
end
|
289
|
-
cached_serializer
|
290
|
-
end
|
291
|
-
|
292
|
-
def _get_or_create_fragment_non_cached_serializer(serializer_class_name)
|
293
|
-
non_cached_serializer = _get_or_create_fragment_serializer "NonCached#{serializer_class_name}"
|
294
|
-
non_cached_serializer.type(self.class._type)
|
295
|
-
non_cached_serializer.fragmented(self)
|
296
|
-
self.class.non_cached_attributes.each do |attribute|
|
297
|
-
options = self.class._attributes_keys[attribute] || {}
|
298
|
-
non_cached_serializer.attribute(attribute, options)
|
299
|
-
end
|
300
|
-
non_cached_serializer
|
301
|
-
end
|
302
|
-
|
303
|
-
def _get_or_create_fragment_serializer(name)
|
304
|
-
return Object.const_get(name) if Object.const_defined?(name)
|
305
|
-
Object.const_set(name, Class.new(ActiveModel::Serializer))
|
306
|
-
end
|
307
|
-
|
308
256
|
def cache_key(adapter_instance)
|
309
257
|
return @cache_key if defined?(@cache_key)
|
310
258
|
|
311
259
|
parts = []
|
312
260
|
parts << object_cache_key
|
313
|
-
parts << adapter_instance.
|
314
|
-
parts <<
|
261
|
+
parts << adapter_instance.cache_key
|
262
|
+
parts << serializer_class._cache_digest unless serializer_class._skip_digest?
|
315
263
|
@cache_key = parts.join('/')
|
316
264
|
end
|
317
265
|
|
@@ -320,14 +268,18 @@ module ActiveModel
|
|
320
268
|
def object_cache_key
|
321
269
|
if object.respond_to?(:cache_key)
|
322
270
|
object.cache_key
|
323
|
-
elsif (serializer_cache_key = (
|
271
|
+
elsif (serializer_cache_key = (serializer_class._cache_key || serializer_class._cache_options[:key]))
|
324
272
|
object_time_safe = object.updated_at
|
325
273
|
object_time_safe = object_time_safe.strftime('%Y%m%d%H%M%S%9N') if object_time_safe.respond_to?(:strftime)
|
326
274
|
"#{serializer_cache_key}/#{object.id}-#{object_time_safe}"
|
327
275
|
else
|
328
|
-
fail UndefinedCacheKey, "#{object.class} must define #cache_key, or the 'key:' option must be passed into '#{
|
276
|
+
fail UndefinedCacheKey, "#{object.class} must define #cache_key, or the 'key:' option must be passed into '#{serializer_class}.cache'"
|
329
277
|
end
|
330
278
|
end
|
279
|
+
|
280
|
+
def serializer_class
|
281
|
+
@serializer_class ||= self.class
|
282
|
+
end
|
331
283
|
end
|
332
284
|
end
|
333
285
|
end
|
@@ -11,22 +11,23 @@ module ActiveModel
|
|
11
11
|
@object = resources
|
12
12
|
@options = options
|
13
13
|
@root = options[:root]
|
14
|
-
|
15
|
-
@serializers = resources.map do |resource|
|
16
|
-
serializer_class = options.fetch(:serializer) { serializer_context_class.serializer_for(resource) }
|
17
|
-
|
18
|
-
if serializer_class.nil? # rubocop:disable Style/GuardClause
|
19
|
-
fail NoSerializerError, "No serializer found for resource: #{resource.inspect}"
|
20
|
-
else
|
21
|
-
serializer_class.new(resource, options.except(:serializer))
|
22
|
-
end
|
23
|
-
end
|
14
|
+
@serializers = serializers_from_resources
|
24
15
|
end
|
25
16
|
|
26
17
|
def success?
|
27
18
|
true
|
28
19
|
end
|
29
20
|
|
21
|
+
# @api private
|
22
|
+
def serializable_hash(adapter_options, options, adapter_instance)
|
23
|
+
include_directive = ActiveModel::Serializer.include_directive_from_options(adapter_options)
|
24
|
+
adapter_options[:cached_attributes] ||= ActiveModel::Serializer.cache_read_multi(self, adapter_instance, include_directive)
|
25
|
+
adapter_opts = adapter_options.merge(include_directive: include_directive)
|
26
|
+
serializers.map do |serializer|
|
27
|
+
serializer.serializable_hash(adapter_opts, options, adapter_instance)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
30
31
|
# TODO: unify naming of root, json_key, and _type. Right now, a serializer's
|
31
32
|
# json_key comes from the root option or the object's model name, by default.
|
32
33
|
# But, if a dev defines a custom `json_key` method with an explicit value,
|
@@ -59,6 +60,25 @@ module ActiveModel
|
|
59
60
|
protected
|
60
61
|
|
61
62
|
attr_reader :serializers, :options
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def serializers_from_resources
|
67
|
+
serializer_context_class = options.fetch(:serializer_context_class, ActiveModel::Serializer)
|
68
|
+
object.map do |resource|
|
69
|
+
serializer_from_resource(resource, serializer_context_class, options)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def serializer_from_resource(resource, serializer_context_class, options)
|
74
|
+
serializer_class = options.fetch(:serializer) { serializer_context_class.serializer_for(resource) }
|
75
|
+
|
76
|
+
if serializer_class.nil? # rubocop:disable Style/GuardClause
|
77
|
+
fail NoSerializerError, "No serializer found for resource: #{resource.inspect}"
|
78
|
+
else
|
79
|
+
serializer_class.new(resource, options.except(:serializer))
|
80
|
+
end
|
81
|
+
end
|
62
82
|
end
|
63
83
|
end
|
64
84
|
end
|
@@ -75,10 +75,10 @@ module ActiveModel
|
|
75
75
|
|
76
76
|
if block
|
77
77
|
block_value = instance_exec(serializer, &block)
|
78
|
-
if block_value
|
79
|
-
serializer.read_attribute_for_serialization(name)
|
80
|
-
else
|
78
|
+
if block_value != :nil
|
81
79
|
block_value
|
80
|
+
elsif @_include_data
|
81
|
+
serializer.read_attribute_for_serialization(name)
|
82
82
|
end
|
83
83
|
else
|
84
84
|
serializer.read_attribute_for_serialization(name)
|
@@ -31,6 +31,12 @@ module ActiveModelSerializers
|
|
31
31
|
[file, lineno]
|
32
32
|
end
|
33
33
|
|
34
|
+
# Memoized default include directive
|
35
|
+
# @return [JSONAPI::IncludeDirective]
|
36
|
+
def self.default_include_directive
|
37
|
+
@default_include_directive ||= JSONAPI::IncludeDirective.new(config.default_includes, allow_wildcard: true)
|
38
|
+
end
|
39
|
+
|
34
40
|
require 'active_model/serializer/version'
|
35
41
|
require 'active_model/serializer'
|
36
42
|
require 'active_model/serializable_resource'
|
@@ -5,11 +5,13 @@ module ActiveModelSerializers
|
|
5
5
|
private_constant :ADAPTER_MAP if defined?(private_constant)
|
6
6
|
|
7
7
|
class << self # All methods are class functions
|
8
|
+
# :nocov:
|
8
9
|
def new(*args)
|
9
10
|
fail ArgumentError, 'Adapters inherit from Adapter::Base.' \
|
10
11
|
"Adapter.new called with args: '#{args.inspect}', from" \
|
11
12
|
"'caller[0]'."
|
12
13
|
end
|
14
|
+
# :nocov:
|
13
15
|
|
14
16
|
def configured_adapter
|
15
17
|
lookup(ActiveModelSerializers.config.adapter)
|
@@ -51,6 +53,10 @@ module ActiveModelSerializers
|
|
51
53
|
self
|
52
54
|
end
|
53
55
|
|
56
|
+
def registered_name(adapter_class)
|
57
|
+
ADAPTER_MAP.key adapter_class
|
58
|
+
end
|
59
|
+
|
54
60
|
# @param adapter [String, Symbol, Class] name to fetch adapter by
|
55
61
|
# @return [ActiveModelSerializers::Adapter] subclass of Adapter
|
56
62
|
# @raise [UnknownAdapterError]
|
@@ -1,75 +1,10 @@
|
|
1
1
|
module ActiveModelSerializers
|
2
2
|
module Adapter
|
3
3
|
class Attributes < Base
|
4
|
-
def initialize(serializer, options = {})
|
5
|
-
super
|
6
|
-
@include_tree = ActiveModel::Serializer::IncludeTree.from_include_args(options[:include] || '*')
|
7
|
-
@cached_attributes = options[:cache_attributes] || {}
|
8
|
-
end
|
9
|
-
|
10
4
|
def serializable_hash(options = nil)
|
11
5
|
options = serialization_options(options)
|
12
|
-
|
13
|
-
|
14
|
-
serializable_hash_for_collection(options)
|
15
|
-
else
|
16
|
-
serializable_hash_for_single_resource(options)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def serializable_hash_for_collection(options)
|
23
|
-
cache_attributes
|
24
|
-
|
25
|
-
serializer.map { |s| Attributes.new(s, instance_options).serializable_hash(options) }
|
26
|
-
end
|
27
|
-
|
28
|
-
def serializable_hash_for_single_resource(options)
|
29
|
-
resource = resource_object_for(options)
|
30
|
-
relationships = resource_relationships(options)
|
31
|
-
resource.merge(relationships)
|
32
|
-
end
|
33
|
-
|
34
|
-
def resource_relationships(options)
|
35
|
-
relationships = {}
|
36
|
-
serializer.associations(@include_tree).each do |association|
|
37
|
-
relationships[association.key] ||= relationship_value_for(association, options)
|
38
|
-
end
|
39
|
-
|
40
|
-
relationships
|
41
|
-
end
|
42
|
-
|
43
|
-
def relationship_value_for(association, options)
|
44
|
-
return association.options[:virtual_value] if association.options[:virtual_value]
|
45
|
-
return unless association.serializer && association.serializer.object
|
46
|
-
|
47
|
-
opts = instance_options.merge(include: @include_tree[association.key])
|
48
|
-
relationship_value = Attributes.new(association.serializer, opts).serializable_hash(options)
|
49
|
-
|
50
|
-
if association.options[:polymorphic] && relationship_value
|
51
|
-
polymorphic_type = association.serializer.object.class.name.underscore
|
52
|
-
relationship_value = { type: polymorphic_type, polymorphic_type.to_sym => relationship_value }
|
53
|
-
end
|
54
|
-
|
55
|
-
relationship_value
|
56
|
-
end
|
57
|
-
|
58
|
-
# Set @cached_attributes
|
59
|
-
def cache_attributes
|
60
|
-
return if @cached_attributes.present?
|
61
|
-
|
62
|
-
@cached_attributes = ActiveModel::Serializer.cache_read_multi(serializer, self, @include_tree)
|
63
|
-
end
|
64
|
-
|
65
|
-
def resource_object_for(options)
|
66
|
-
if serializer.class.cache_enabled?
|
67
|
-
@cached_attributes.fetch(serializer.cache_key(self)) do
|
68
|
-
serializer.cached_fields(options[:fields], self)
|
69
|
-
end
|
70
|
-
else
|
71
|
-
serializer.cached_fields(options[:fields], self)
|
72
|
-
end
|
6
|
+
options[:fields] ||= instance_options[:fields]
|
7
|
+
serializer.serializable_hash(instance_options, options, self)
|
73
8
|
end
|
74
9
|
end
|
75
10
|
end
|