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
@@ -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
|