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
@@ -8,6 +8,40 @@ module ActiveModelSerializers
|
|
8
8
|
ActiveModelSerializers::Adapter.register(subclass)
|
9
9
|
end
|
10
10
|
|
11
|
+
# Sets the default transform for the adapter.
|
12
|
+
#
|
13
|
+
# @return [Symbol] the default transform for the adapter
|
14
|
+
def self.default_key_transform
|
15
|
+
:unaltered
|
16
|
+
end
|
17
|
+
|
18
|
+
# Determines the transform to use in order of precedence:
|
19
|
+
# adapter option, global config, adapter default.
|
20
|
+
#
|
21
|
+
# @param options [Object]
|
22
|
+
# @return [Symbol] the transform to use
|
23
|
+
def self.transform(options)
|
24
|
+
return options[:key_transform] if options && options[:key_transform]
|
25
|
+
ActiveModelSerializers.config.key_transform || default_key_transform
|
26
|
+
end
|
27
|
+
|
28
|
+
# Transforms the casing of the supplied value.
|
29
|
+
#
|
30
|
+
# @param value [Object] the value to be transformed
|
31
|
+
# @param options [Object] serializable resource options
|
32
|
+
# @return [Symbol] the default transform for the adapter
|
33
|
+
def self.transform_key_casing!(value, options)
|
34
|
+
KeyTransform.send(transform(options), value)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.cache_key
|
38
|
+
@cache_key ||= ActiveModelSerializers::Adapter.registered_name(self)
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.fragment_cache(cached_hash, non_cached_hash)
|
42
|
+
non_cached_hash.merge cached_hash
|
43
|
+
end
|
44
|
+
|
11
45
|
attr_reader :serializer, :instance_options
|
12
46
|
|
13
47
|
def initialize(serializer, options = {})
|
@@ -15,10 +49,6 @@ module ActiveModelSerializers
|
|
15
49
|
@instance_options = options
|
16
50
|
end
|
17
51
|
|
18
|
-
def cached_name
|
19
|
-
@cached_name ||= self.class.name.demodulize.underscore
|
20
|
-
end
|
21
|
-
|
22
52
|
# Subclasses that implement this method must first call
|
23
53
|
# options = serialization_options(options)
|
24
54
|
def serializable_hash(_options = nil)
|
@@ -29,14 +59,12 @@ module ActiveModelSerializers
|
|
29
59
|
serializable_hash(options)
|
30
60
|
end
|
31
61
|
|
32
|
-
def
|
33
|
-
|
62
|
+
def cache_key
|
63
|
+
self.class.cache_key
|
34
64
|
end
|
35
65
|
|
36
|
-
def
|
37
|
-
|
38
|
-
yield
|
39
|
-
end
|
66
|
+
def fragment_cache(cached_hash, non_cached_hash)
|
67
|
+
self.class.fragment_cache(cached_hash, non_cached_hash)
|
40
68
|
end
|
41
69
|
|
42
70
|
private
|
@@ -50,34 +78,6 @@ module ActiveModelSerializers
|
|
50
78
|
def root
|
51
79
|
serializer.json_key.to_sym if serializer.json_key
|
52
80
|
end
|
53
|
-
|
54
|
-
class << self
|
55
|
-
# Sets the default transform for the adapter.
|
56
|
-
#
|
57
|
-
# @return [Symbol] the default transform for the adapter
|
58
|
-
def default_key_transform
|
59
|
-
:unaltered
|
60
|
-
end
|
61
|
-
|
62
|
-
# Determines the transform to use in order of precedence:
|
63
|
-
# adapter option, global config, adapter default.
|
64
|
-
#
|
65
|
-
# @param options [Object]
|
66
|
-
# @return [Symbol] the transform to use
|
67
|
-
def transform(options)
|
68
|
-
return options[:key_transform] if options && options[:key_transform]
|
69
|
-
ActiveModelSerializers.config.key_transform || default_key_transform
|
70
|
-
end
|
71
|
-
|
72
|
-
# Transforms the casing of the supplied value.
|
73
|
-
#
|
74
|
-
# @param value [Object] the value to be transformed
|
75
|
-
# @param options [Object] serializable resource options
|
76
|
-
# @return [Symbol] the default transform for the adapter
|
77
|
-
def transform_key_casing!(value, options)
|
78
|
-
KeyTransform.send(transform(options), value)
|
79
|
-
end
|
80
|
-
end
|
81
81
|
end
|
82
82
|
end
|
83
83
|
end
|
@@ -31,16 +31,27 @@ module ActiveModelSerializers
|
|
31
31
|
autoload :Error
|
32
32
|
autoload :Deserialization
|
33
33
|
|
34
|
+
def self.default_key_transform
|
35
|
+
:dash
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.fragment_cache(cached_hash, non_cached_hash, root = true)
|
39
|
+
core_cached = cached_hash.first
|
40
|
+
core_non_cached = non_cached_hash.first
|
41
|
+
no_root_cache = cached_hash.delete_if { |key, _value| key == core_cached[0] }
|
42
|
+
no_root_non_cache = non_cached_hash.delete_if { |key, _value| key == core_non_cached[0] }
|
43
|
+
cached_resource = (core_cached[1]) ? core_cached[1].deep_merge(core_non_cached[1]) : core_non_cached[1]
|
44
|
+
hash = root ? { root => cached_resource } : cached_resource
|
45
|
+
|
46
|
+
hash.deep_merge no_root_non_cache.deep_merge no_root_cache
|
47
|
+
end
|
48
|
+
|
34
49
|
def initialize(serializer, options = {})
|
35
50
|
super
|
36
|
-
@
|
51
|
+
@include_directive = JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: true)
|
37
52
|
@fieldset = options[:fieldset] || ActiveModel::Serializer::Fieldset.new(options.delete(:fields))
|
38
53
|
end
|
39
54
|
|
40
|
-
def self.default_key_transform
|
41
|
-
:dash
|
42
|
-
end
|
43
|
-
|
44
55
|
# {http://jsonapi.org/format/#crud Requests are transactional, i.e. success or failure}
|
45
56
|
# {http://jsonapi.org/format/#document-top-level data and errors MUST NOT coexist in the same document.}
|
46
57
|
def serializable_hash(*)
|
@@ -52,6 +63,11 @@ module ActiveModelSerializers
|
|
52
63
|
self.class.transform_key_casing!(document, instance_options)
|
53
64
|
end
|
54
65
|
|
66
|
+
def fragment_cache(cached_hash, non_cached_hash)
|
67
|
+
root = !instance_options.include?(:include)
|
68
|
+
self.class.fragment_cache(cached_hash, non_cached_hash, root)
|
69
|
+
end
|
70
|
+
|
55
71
|
# {http://jsonapi.org/format/#document-top-level Primary data}
|
56
72
|
# definition:
|
57
73
|
# ☐ toplevel_data (required)
|
@@ -174,18 +190,6 @@ module ActiveModelSerializers
|
|
174
190
|
hash
|
175
191
|
end
|
176
192
|
|
177
|
-
def fragment_cache(cached_hash, non_cached_hash)
|
178
|
-
root = false if instance_options.include?(:include)
|
179
|
-
core_cached = cached_hash.first
|
180
|
-
core_non_cached = non_cached_hash.first
|
181
|
-
no_root_cache = cached_hash.delete_if { |key, _value| key == core_cached[0] }
|
182
|
-
no_root_non_cache = non_cached_hash.delete_if { |key, _value| key == core_non_cached[0] }
|
183
|
-
cached_resource = (core_cached[1]) ? core_cached[1].deep_merge(core_non_cached[1]) : core_non_cached[1]
|
184
|
-
hash = root ? { root => cached_resource } : cached_resource
|
185
|
-
|
186
|
-
hash.deep_merge no_root_non_cache.deep_merge no_root_cache
|
187
|
-
end
|
188
|
-
|
189
193
|
protected
|
190
194
|
|
191
195
|
attr_reader :fieldset
|
@@ -232,7 +236,7 @@ module ActiveModelSerializers
|
|
232
236
|
@included = []
|
233
237
|
@resource_identifiers = Set.new
|
234
238
|
serializers.each { |serializer| process_resource(serializer, true) }
|
235
|
-
serializers.each { |serializer| process_relationships(serializer, @
|
239
|
+
serializers.each { |serializer| process_relationships(serializer, @include_directive) }
|
236
240
|
|
237
241
|
[@primary, @included]
|
238
242
|
end
|
@@ -251,21 +255,21 @@ module ActiveModelSerializers
|
|
251
255
|
true
|
252
256
|
end
|
253
257
|
|
254
|
-
def process_relationships(serializer,
|
255
|
-
serializer.associations(
|
256
|
-
process_relationship(association.serializer,
|
258
|
+
def process_relationships(serializer, include_directive)
|
259
|
+
serializer.associations(include_directive).each do |association|
|
260
|
+
process_relationship(association.serializer, include_directive[association.key])
|
257
261
|
end
|
258
262
|
end
|
259
263
|
|
260
|
-
def process_relationship(serializer,
|
264
|
+
def process_relationship(serializer, include_directive)
|
261
265
|
if serializer.respond_to?(:each)
|
262
|
-
serializer.each { |s| process_relationship(s,
|
266
|
+
serializer.each { |s| process_relationship(s, include_directive) }
|
263
267
|
return
|
264
268
|
end
|
265
269
|
return unless serializer && serializer.object
|
266
270
|
return unless process_resource(serializer, false)
|
267
271
|
|
268
|
-
process_relationships(serializer,
|
272
|
+
process_relationships(serializer, include_directive)
|
269
273
|
end
|
270
274
|
|
271
275
|
# {http://jsonapi.org/format/#document-resource-object-attributes Document Resource Object Attributes}
|
@@ -290,7 +294,7 @@ module ActiveModelSerializers
|
|
290
294
|
|
291
295
|
# {http://jsonapi.org/format/#document-resource-objects Document Resource Objects}
|
292
296
|
def resource_object_for(serializer)
|
293
|
-
resource_object =
|
297
|
+
resource_object = serializer.fetch(self) do
|
294
298
|
resource_object = ResourceIdentifier.new(serializer, instance_options).as_json
|
295
299
|
|
296
300
|
requested_fields = fieldset && fieldset.fields_for(resource_object[:type])
|
@@ -429,8 +433,11 @@ module ActiveModelSerializers
|
|
429
433
|
# meta: meta
|
430
434
|
# }.reject! {|_,v| v.nil? }
|
431
435
|
def relationships_for(serializer, requested_associations)
|
432
|
-
|
433
|
-
|
436
|
+
include_directive = JSONAPI::IncludeDirective.new(
|
437
|
+
requested_associations,
|
438
|
+
allow_wildcard: true
|
439
|
+
)
|
440
|
+
serializer.associations(include_directive).each_with_object({}) do |association, hash|
|
434
441
|
hash[association.key] = Relationship.new(
|
435
442
|
serializer,
|
436
443
|
association.serializer,
|
@@ -467,7 +474,8 @@ module ActiveModelSerializers
|
|
467
474
|
# }.reject! {|_,v| v.nil? }
|
468
475
|
def links_for(serializer)
|
469
476
|
serializer._links.each_with_object({}) do |(name, value), hash|
|
470
|
-
|
477
|
+
result = Link.new(serializer, value).as_json
|
478
|
+
hash[name] = result if result
|
471
479
|
end
|
472
480
|
end
|
473
481
|
|
@@ -2,6 +2,7 @@ module ActiveModelSerializers
|
|
2
2
|
module Adapter
|
3
3
|
class JsonApi < Base
|
4
4
|
class PaginationLinks
|
5
|
+
MissingSerializationContextError = Class.new(KeyError)
|
5
6
|
FIRST_PAGE = 1
|
6
7
|
|
7
8
|
attr_reader :collection, :context
|
@@ -9,7 +10,13 @@ module ActiveModelSerializers
|
|
9
10
|
def initialize(collection, adapter_options)
|
10
11
|
@collection = collection
|
11
12
|
@adapter_options = adapter_options
|
12
|
-
@context = adapter_options.fetch(:serialization_context)
|
13
|
+
@context = adapter_options.fetch(:serialization_context) do
|
14
|
+
fail MissingSerializationContextError, <<-EOF.freeze
|
15
|
+
JsonApi::PaginationLinks requires a ActiveModelSerializers::SerializationContext.
|
16
|
+
Please pass a ':serialization_context' option or
|
17
|
+
override CollectionSerializer#paginated? to return 'false'.
|
18
|
+
EOF
|
19
|
+
end
|
13
20
|
end
|
14
21
|
|
15
22
|
def as_json
|
@@ -36,8 +36,7 @@ module ActiveModelSerializers
|
|
36
36
|
target = is_a?(Module) ? "#{self}." : "#{self.class}#"
|
37
37
|
msg = ["NOTE: #{target}#{name} is deprecated",
|
38
38
|
replacement == :none ? ' with no replacement' : "; use #{replacement} instead",
|
39
|
-
"\n#{target}#{name} called from #{ActiveModelSerializers.location_of_caller.join(":")}"
|
40
|
-
]
|
39
|
+
"\n#{target}#{name} called from #{ActiveModelSerializers.location_of_caller.join(":")}"]
|
41
40
|
warn "#{msg.join}."
|
42
41
|
send old, *args, &block
|
43
42
|
end
|
@@ -38,6 +38,7 @@ module ActiveModelSerializers
|
|
38
38
|
end
|
39
39
|
|
40
40
|
# The following methods are needed to be minimally implemented for ActiveModel::Errors
|
41
|
+
# :nocov:
|
41
42
|
def self.human_attribute_name(attr, _options = {})
|
42
43
|
attr
|
43
44
|
end
|
@@ -45,5 +46,6 @@ module ActiveModelSerializers
|
|
45
46
|
def self.lookup_ancestors
|
46
47
|
[self]
|
47
48
|
end
|
49
|
+
# :nocov:
|
48
50
|
end
|
49
51
|
end
|
@@ -32,11 +32,13 @@ module ActiveModelSerializers
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
# :nocov:
|
35
36
|
generators do |app|
|
36
37
|
Rails::Generators.configure!(app.config.generators)
|
37
38
|
Rails::Generators.hidden_namespaces.uniq!
|
38
39
|
require 'generators/rails/resource_override'
|
39
40
|
end
|
41
|
+
# :nocov:
|
40
42
|
|
41
43
|
if Rails.env.test?
|
42
44
|
ActionController::TestCase.send(:include, ActiveModelSerializers::Test::Schema)
|
@@ -22,43 +22,54 @@
|
|
22
22
|
# render jsonapi: model
|
23
23
|
#
|
24
24
|
# No wrapper format needed as it does not apply (i.e. no `wrap_parameters format: [jsonapi]`)
|
25
|
-
|
26
25
|
module ActiveModelSerializers::Jsonapi
|
27
26
|
MEDIA_TYPE = 'application/vnd.api+json'.freeze
|
28
27
|
HEADERS = {
|
29
28
|
response: { 'CONTENT_TYPE'.freeze => MEDIA_TYPE },
|
30
29
|
request: { 'ACCEPT'.freeze => MEDIA_TYPE }
|
31
30
|
}.freeze
|
31
|
+
|
32
|
+
def self.install
|
33
|
+
# actionpack/lib/action_dispatch/http/mime_types.rb
|
34
|
+
Mime::Type.register MEDIA_TYPE, :jsonapi
|
35
|
+
|
36
|
+
if Rails::VERSION::MAJOR >= 5
|
37
|
+
ActionDispatch::Request.parameter_parsers[:jsonapi] = parser
|
38
|
+
else
|
39
|
+
ActionDispatch::ParamsParser::DEFAULT_PARSERS[Mime[:jsonapi]] = parser
|
40
|
+
end
|
41
|
+
|
42
|
+
# ref https://github.com/rails/rails/pull/21496
|
43
|
+
ActionController::Renderers.add :jsonapi do |json, options|
|
44
|
+
json = serialize_jsonapi(json, options).to_json(options) unless json.is_a?(String)
|
45
|
+
self.content_type ||= Mime[:jsonapi]
|
46
|
+
self.response_body = json
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Proposal: should actually deserialize the JSON API params
|
51
|
+
# to the hash format expected by `ActiveModel::Serializers::JSON`
|
52
|
+
# actionpack/lib/action_dispatch/http/parameters.rb
|
53
|
+
def self.parser
|
54
|
+
lambda do |body|
|
55
|
+
data = JSON.parse(body)
|
56
|
+
data = { :_json => data } unless data.is_a?(Hash)
|
57
|
+
data.with_indifferent_access
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
32
61
|
module ControllerSupport
|
33
62
|
def serialize_jsonapi(json, options)
|
34
63
|
options[:adapter] = :json_api
|
35
|
-
options.fetch(:serialization_context)
|
64
|
+
options.fetch(:serialization_context) do
|
65
|
+
options[:serialization_context] = ActiveModelSerializers::SerializationContext.new(request)
|
66
|
+
end
|
36
67
|
get_serializer(json, options)
|
37
68
|
end
|
38
69
|
end
|
39
70
|
end
|
40
71
|
|
41
|
-
|
42
|
-
Mime::Type.register ActiveModelSerializers::Jsonapi::MEDIA_TYPE, :jsonapi
|
43
|
-
|
44
|
-
parsers = Rails::VERSION::MAJOR >= 5 ? ActionDispatch::Http::Parameters : ActionDispatch::ParamsParser
|
45
|
-
media_type = Mime::Type.lookup(ActiveModelSerializers::Jsonapi::MEDIA_TYPE)
|
46
|
-
|
47
|
-
# Proposal: should actually deserialize the JSON API params
|
48
|
-
# to the hash format expected by `ActiveModel::Serializers::JSON`
|
49
|
-
# actionpack/lib/action_dispatch/http/parameters.rb
|
50
|
-
parsers::DEFAULT_PARSERS[media_type] = lambda do |body|
|
51
|
-
data = JSON.parse(body)
|
52
|
-
data = { :_json => data } unless data.is_a?(Hash)
|
53
|
-
data.with_indifferent_access
|
54
|
-
end
|
55
|
-
|
56
|
-
# ref https://github.com/rails/rails/pull/21496
|
57
|
-
ActionController::Renderers.add :jsonapi do |json, options|
|
58
|
-
json = serialize_jsonapi(json, options).to_json(options) unless json.is_a?(String)
|
59
|
-
self.content_type ||= media_type
|
60
|
-
self.response_body = json
|
61
|
-
end
|
72
|
+
ActiveModelSerializers::Jsonapi.install
|
62
73
|
|
63
74
|
ActiveSupport.on_load(:action_controller) do
|
64
75
|
include ActiveModelSerializers::Jsonapi::ControllerSupport
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_support/core_ext/array/extract_options'
|
1
2
|
module ActiveModelSerializers
|
2
3
|
class SerializationContext
|
3
4
|
class << self
|
@@ -22,9 +23,15 @@ module ActiveModelSerializers
|
|
22
23
|
|
23
24
|
attr_reader :request_url, :query_parameters, :key_transform
|
24
25
|
|
25
|
-
def initialize(
|
26
|
-
|
27
|
-
|
26
|
+
def initialize(*args)
|
27
|
+
options = args.extract_options!
|
28
|
+
if args.size == 1
|
29
|
+
request = args.pop
|
30
|
+
options[:request_url] = request.original_url[/\A[^?]+/]
|
31
|
+
options[:query_parameters] = request.query_parameters
|
32
|
+
end
|
33
|
+
@request_url = options.delete(:request_url)
|
34
|
+
@query_parameters = options.delete(:query_parameters)
|
28
35
|
@url_helpers = options.delete(:url_helpers) || self.class.url_helpers
|
29
36
|
@default_url_options = options.delete(:default_url_options) || self.class.default_url_options
|
30
37
|
end
|
@@ -2,14 +2,31 @@
|
|
2
2
|
#
|
3
3
|
# Serializer options can be passed as a hash from your Grape endpoint using env[:active_model_serializer_options],
|
4
4
|
# or better yet user the render helper in Grape::Helpers::ActiveModelSerializers
|
5
|
+
|
6
|
+
require 'active_model_serializers/serialization_context'
|
7
|
+
|
5
8
|
module Grape
|
6
9
|
module Formatters
|
7
10
|
module ActiveModelSerializers
|
8
11
|
def self.call(resource, env)
|
9
|
-
serializer_options =
|
10
|
-
serializer_options.merge!(env[:active_model_serializer_options]) if env[:active_model_serializer_options]
|
12
|
+
serializer_options = build_serializer_options(env)
|
11
13
|
::ActiveModelSerializers::SerializableResource.new(resource, serializer_options).to_json
|
12
14
|
end
|
15
|
+
|
16
|
+
def self.build_serializer_options(env)
|
17
|
+
ams_options = env[:active_model_serializer_options] || {}
|
18
|
+
|
19
|
+
# Add serialization context
|
20
|
+
ams_options.fetch(:serialization_context) do
|
21
|
+
request = env['grape.request']
|
22
|
+
ams_options[:serialization_context] = ::ActiveModelSerializers::SerializationContext.new(
|
23
|
+
request_url: request.url[/\A[^?]+/],
|
24
|
+
query_parameters: request.params
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
ams_options
|
29
|
+
end
|
13
30
|
end
|
14
31
|
end
|
15
32
|
end
|