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