tiny-max-kit 0.0.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 +7 -0
- data/active_model_serializers-0.10.16/CHANGELOG.md +793 -0
- data/active_model_serializers-0.10.16/MIT-LICENSE +22 -0
- data/active_model_serializers-0.10.16/README.md +304 -0
- data/active_model_serializers-0.10.16/lib/action_controller/serialization.rb +76 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializable_resource.rb +13 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/adapter/attributes.rb +17 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/adapter/base.rb +20 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/adapter/json.rb +17 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/adapter/json_api.rb +17 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/adapter/null.rb +17 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/adapter.rb +26 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/array_serializer.rb +14 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/association.rb +73 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/attribute.rb +27 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/belongs_to_reflection.rb +13 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/collection_serializer.rb +99 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/concerns/caching.rb +305 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/error_serializer.rb +16 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/errors_serializer.rb +34 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/field.rb +92 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/fieldset.rb +33 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/has_many_reflection.rb +12 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/has_one_reflection.rb +9 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/lazy_association.rb +99 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/link.rb +23 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/lint.rb +152 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/null.rb +19 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/reflection.rb +212 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer/version.rb +7 -0
- data/active_model_serializers-0.10.16/lib/active_model/serializer.rb +430 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/adapter/attributes.rb +36 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/adapter/base.rb +85 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/adapter/json.rb +23 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/adapter/json_api/deserialization.rb +215 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/adapter/json_api/error.rb +98 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/adapter/json_api/jsonapi.rb +51 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/adapter/json_api/link.rb +85 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/adapter/json_api/meta.rb +39 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/adapter/json_api/pagination_links.rb +94 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/adapter/json_api/relationship.rb +106 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/adapter/json_api/resource_identifier.rb +68 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/adapter/json_api.rb +535 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/adapter/null.rb +11 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/adapter.rb +100 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/callbacks.rb +57 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/deprecate.rb +56 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/deserialization.rb +17 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/json_pointer.rb +16 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/logging.rb +124 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/lookup_chain.rb +82 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/model.rb +132 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/railtie.rb +62 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/register_jsonapi_renderer.rb +80 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/serializable_resource.rb +84 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/serialization_context.rb +41 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/test/schema.rb +140 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/test/serializer.rb +127 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers/test.rb +9 -0
- data/active_model_serializers-0.10.16/lib/active_model_serializers.rb +63 -0
- data/active_model_serializers-0.10.16/lib/generators/rails/USAGE +6 -0
- data/active_model_serializers-0.10.16/lib/generators/rails/resource_override.rb +12 -0
- data/active_model_serializers-0.10.16/lib/generators/rails/serializer_generator.rb +38 -0
- data/active_model_serializers-0.10.16/lib/generators/rails/templates/serializer.rb.erb +8 -0
- data/active_model_serializers-0.10.16/lib/grape/active_model_serializers.rb +18 -0
- data/active_model_serializers-0.10.16/lib/grape/formatters/active_model_serializers.rb +34 -0
- data/active_model_serializers-0.10.16/lib/grape/helpers/active_model_serializers.rb +19 -0
- data/active_model_serializers-0.10.16/lib/tasks/rubocop.rake +60 -0
- data/tiny-max-kit.gemspec +12 -0
- metadata +109 -0
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'jsonapi/include_directive'
|
|
4
|
+
require 'active_model/serializer/collection_serializer'
|
|
5
|
+
require 'active_model/serializer/array_serializer'
|
|
6
|
+
require 'active_model/serializer/error_serializer'
|
|
7
|
+
require 'active_model/serializer/errors_serializer'
|
|
8
|
+
require 'active_model/serializer/concerns/caching'
|
|
9
|
+
require 'active_model/serializer/fieldset'
|
|
10
|
+
require 'active_model/serializer/lint'
|
|
11
|
+
|
|
12
|
+
# ActiveModel::Serializer is an abstract class that is
|
|
13
|
+
# reified when subclassed to decorate a resource.
|
|
14
|
+
module ActiveModel
|
|
15
|
+
class Serializer
|
|
16
|
+
class_attribute :config
|
|
17
|
+
self.config = ActiveSupport::OrderedOptions.new
|
|
18
|
+
|
|
19
|
+
undef_method :select, :display # These IO methods, which are mixed into Kernel,
|
|
20
|
+
# sometimes conflict with attribute names. We don't need these IO methods.
|
|
21
|
+
|
|
22
|
+
# @see #serializable_hash for more details on these valid keys.
|
|
23
|
+
SERIALIZABLE_HASH_VALID_KEYS = [:only, :except, :methods, :include, :root].freeze
|
|
24
|
+
extend ActiveSupport::Autoload
|
|
25
|
+
eager_autoload do
|
|
26
|
+
autoload :Adapter
|
|
27
|
+
autoload :Null
|
|
28
|
+
autoload :Attribute
|
|
29
|
+
autoload :Link
|
|
30
|
+
autoload :Association
|
|
31
|
+
autoload :Reflection
|
|
32
|
+
autoload :BelongsToReflection
|
|
33
|
+
autoload :HasOneReflection
|
|
34
|
+
autoload :HasManyReflection
|
|
35
|
+
end
|
|
36
|
+
include Caching
|
|
37
|
+
|
|
38
|
+
# @param resource [ActiveRecord::Base, ActiveModelSerializers::Model]
|
|
39
|
+
# @return [ActiveModel::Serializer]
|
|
40
|
+
# Preferentially returns
|
|
41
|
+
# 1. resource.serializer_class
|
|
42
|
+
# 2. ArraySerializer when resource is a collection
|
|
43
|
+
# 3. options[:serializer]
|
|
44
|
+
# 4. lookup serializer when resource is a Class
|
|
45
|
+
def self.serializer_for(resource_or_class, options = {})
|
|
46
|
+
if resource_or_class.respond_to?(:serializer_class)
|
|
47
|
+
resource_or_class.serializer_class
|
|
48
|
+
elsif resource_or_class.respond_to?(:to_ary)
|
|
49
|
+
config.collection_serializer
|
|
50
|
+
else
|
|
51
|
+
resource_class = resource_or_class.class == Class ? resource_or_class : resource_or_class.class
|
|
52
|
+
options.fetch(:serializer) { get_serializer_for(resource_class, options[:namespace]) }
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @see ActiveModelSerializers::Adapter.lookup
|
|
57
|
+
# Deprecated
|
|
58
|
+
def self.adapter
|
|
59
|
+
ActiveModelSerializers::Adapter.lookup(config.adapter)
|
|
60
|
+
end
|
|
61
|
+
class << self
|
|
62
|
+
extend ActiveModelSerializers::Deprecate
|
|
63
|
+
deprecate :adapter, 'ActiveModelSerializers::Adapter.configured_adapter'
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# @api private
|
|
67
|
+
def self.serializer_lookup_chain_for(klass, namespace = nil)
|
|
68
|
+
lookups = ActiveModelSerializers.config.serializer_lookup_chain
|
|
69
|
+
Array[*lookups].flat_map do |lookup|
|
|
70
|
+
lookup.call(klass, self, namespace)
|
|
71
|
+
end.compact
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Used to cache serializer name => serializer class
|
|
75
|
+
# when looked up by Serializer.get_serializer_for.
|
|
76
|
+
def self.serializers_cache
|
|
77
|
+
@serializers_cache ||= Concurrent::Map.new
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# @api private
|
|
81
|
+
# Find a serializer from a class and caches the lookup.
|
|
82
|
+
# Preferentially returns:
|
|
83
|
+
# 1. class name appended with "Serializer"
|
|
84
|
+
# 2. try again with superclass, if present
|
|
85
|
+
# 3. nil
|
|
86
|
+
def self.get_serializer_for(klass, namespace = nil)
|
|
87
|
+
return nil unless config.serializer_lookup_enabled
|
|
88
|
+
|
|
89
|
+
cache_key = ActiveSupport::Cache.expand_cache_key(klass, namespace)
|
|
90
|
+
serializers_cache.fetch_or_store(cache_key) do
|
|
91
|
+
# NOTE(beauby): When we drop 1.9.3 support we can lazify the map for perfs.
|
|
92
|
+
lookup_chain = serializer_lookup_chain_for(klass, namespace)
|
|
93
|
+
serializer_class = lookup_chain.map(&:safe_constantize).find { |x| x && x < ActiveModel::Serializer }
|
|
94
|
+
|
|
95
|
+
if serializer_class
|
|
96
|
+
serializer_class
|
|
97
|
+
elsif klass.superclass
|
|
98
|
+
get_serializer_for(klass.superclass, namespace)
|
|
99
|
+
else
|
|
100
|
+
nil # No serializer found
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# @api private
|
|
106
|
+
def self.include_directive_from_options(options)
|
|
107
|
+
if options[:include_directive]
|
|
108
|
+
options[:include_directive]
|
|
109
|
+
elsif options[:include]
|
|
110
|
+
JSONAPI::IncludeDirective.new(options[:include], allow_wildcard: true)
|
|
111
|
+
else
|
|
112
|
+
ActiveModelSerializers.default_include_directive
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# @api private
|
|
117
|
+
def self.serialization_adapter_instance
|
|
118
|
+
@serialization_adapter_instance ||= ActiveModelSerializers::Adapter::Attributes
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Preferred interface is ActiveModelSerializers.config
|
|
122
|
+
# BEGIN DEFAULT CONFIGURATION
|
|
123
|
+
config.collection_serializer = ActiveModel::Serializer::CollectionSerializer
|
|
124
|
+
config.serializer_lookup_enabled = true
|
|
125
|
+
|
|
126
|
+
# @deprecated Use {#config.collection_serializer=} instead of this. Is
|
|
127
|
+
# compatibility layer for ArraySerializer.
|
|
128
|
+
def config.array_serializer=(collection_serializer)
|
|
129
|
+
self.collection_serializer = collection_serializer
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# @deprecated Use {#config.collection_serializer} instead of this. Is
|
|
133
|
+
# compatibility layer for ArraySerializer.
|
|
134
|
+
def config.array_serializer
|
|
135
|
+
collection_serializer
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
config.default_includes = '*'
|
|
139
|
+
config.adapter = :attributes
|
|
140
|
+
config.key_transform = nil
|
|
141
|
+
config.jsonapi_pagination_links_enabled = true
|
|
142
|
+
config.jsonapi_resource_type = :plural
|
|
143
|
+
config.jsonapi_namespace_separator = '-'.freeze
|
|
144
|
+
config.jsonapi_version = '1.0'
|
|
145
|
+
config.jsonapi_toplevel_meta = {}
|
|
146
|
+
# Make JSON API top-level jsonapi member opt-in
|
|
147
|
+
# ref: http://jsonapi.org/format/#document-top-level
|
|
148
|
+
config.jsonapi_include_toplevel_object = false
|
|
149
|
+
config.jsonapi_use_foreign_key_on_belongs_to_relationship = false
|
|
150
|
+
config.include_data_default = true
|
|
151
|
+
# Raise ActiveModel::Serializer::CollectionSerializer::CannotInferRootKeyError when cannot infer root key from collection type
|
|
152
|
+
config.raise_cannot_infer_root_key_error = true
|
|
153
|
+
|
|
154
|
+
# For configuring how serializers are found.
|
|
155
|
+
# This should be an array of procs.
|
|
156
|
+
#
|
|
157
|
+
# The priority of the output is that the first item
|
|
158
|
+
# in the evaluated result array will take precedence
|
|
159
|
+
# over other possible serializer paths.
|
|
160
|
+
#
|
|
161
|
+
# i.e.: First match wins.
|
|
162
|
+
#
|
|
163
|
+
# @example output
|
|
164
|
+
# => [
|
|
165
|
+
# "CustomNamespace::ResourceSerializer",
|
|
166
|
+
# "ParentSerializer::ResourceSerializer",
|
|
167
|
+
# "ResourceNamespace::ResourceSerializer" ,
|
|
168
|
+
# "ResourceSerializer"]
|
|
169
|
+
#
|
|
170
|
+
# If CustomNamespace::ResourceSerializer exists, it will be used
|
|
171
|
+
# for serialization
|
|
172
|
+
config.serializer_lookup_chain = ActiveModelSerializers::LookupChain::DEFAULT.dup
|
|
173
|
+
|
|
174
|
+
config.schema_path = 'test/support/schemas'
|
|
175
|
+
# END DEFAULT CONFIGURATION
|
|
176
|
+
|
|
177
|
+
with_options instance_writer: false, instance_reader: false do |serializer|
|
|
178
|
+
serializer.class_attribute :_attributes_data # @api private
|
|
179
|
+
self._attributes_data ||= {}
|
|
180
|
+
end
|
|
181
|
+
with_options instance_writer: false, instance_reader: true do |serializer|
|
|
182
|
+
serializer.class_attribute :_reflections
|
|
183
|
+
self._reflections ||= {}
|
|
184
|
+
serializer.class_attribute :_links # @api private
|
|
185
|
+
self._links ||= {}
|
|
186
|
+
serializer.class_attribute :_meta # @api private
|
|
187
|
+
serializer.class_attribute :_type # @api private
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def self.inherited(base)
|
|
191
|
+
super
|
|
192
|
+
base._attributes_data = _attributes_data.dup
|
|
193
|
+
base._reflections = _reflections.dup
|
|
194
|
+
base._links = _links.dup
|
|
195
|
+
base.config = ActiveSupport::InheritableOptions.new(config)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# @return [Array<Symbol>] Key names of declared attributes
|
|
199
|
+
# @see Serializer::attribute
|
|
200
|
+
def self._attributes
|
|
201
|
+
_attributes_data.keys
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# BEGIN SERIALIZER MACROS
|
|
205
|
+
|
|
206
|
+
# @example
|
|
207
|
+
# class AdminAuthorSerializer < ActiveModel::Serializer
|
|
208
|
+
# attributes :id, :name, :recent_edits
|
|
209
|
+
def self.attributes(*attrs)
|
|
210
|
+
attrs = attrs.first if attrs.first.class == Array
|
|
211
|
+
|
|
212
|
+
attrs.each do |attr|
|
|
213
|
+
attribute(attr)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# @example
|
|
218
|
+
# class AdminAuthorSerializer < ActiveModel::Serializer
|
|
219
|
+
# attributes :id, :recent_edits
|
|
220
|
+
# attribute :name, key: :title
|
|
221
|
+
#
|
|
222
|
+
# attribute :full_name do
|
|
223
|
+
# "#{object.first_name} #{object.last_name}"
|
|
224
|
+
# end
|
|
225
|
+
#
|
|
226
|
+
# def recent_edits
|
|
227
|
+
# object.edits.last(5)
|
|
228
|
+
# end
|
|
229
|
+
def self.attribute(attr, options = {}, &block)
|
|
230
|
+
key = options.fetch(:key, attr)
|
|
231
|
+
_attributes_data[key] = Attribute.new(attr, options, block)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# @param [Symbol] name of the association
|
|
235
|
+
# @param [Hash<Symbol => any>] options for the reflection
|
|
236
|
+
# @return [void]
|
|
237
|
+
#
|
|
238
|
+
# @example
|
|
239
|
+
# has_many :comments, serializer: CommentSummarySerializer
|
|
240
|
+
#
|
|
241
|
+
def self.has_many(name, options = {}, &block) # rubocop:disable Style/PredicateName
|
|
242
|
+
associate(HasManyReflection.new(name, options, block))
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# @param [Symbol] name of the association
|
|
246
|
+
# @param [Hash<Symbol => any>] options for the reflection
|
|
247
|
+
# @return [void]
|
|
248
|
+
#
|
|
249
|
+
# @example
|
|
250
|
+
# belongs_to :author, serializer: AuthorSerializer
|
|
251
|
+
#
|
|
252
|
+
def self.belongs_to(name, options = {}, &block)
|
|
253
|
+
associate(BelongsToReflection.new(name, options, block))
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# @param [Symbol] name of the association
|
|
257
|
+
# @param [Hash<Symbol => any>] options for the reflection
|
|
258
|
+
# @return [void]
|
|
259
|
+
#
|
|
260
|
+
# @example
|
|
261
|
+
# has_one :author, serializer: AuthorSerializer
|
|
262
|
+
#
|
|
263
|
+
def self.has_one(name, options = {}, &block) # rubocop:disable Style/PredicateName
|
|
264
|
+
associate(HasOneReflection.new(name, options, block))
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
# Add reflection and define {name} accessor.
|
|
268
|
+
# @param [ActiveModel::Serializer::Reflection] reflection
|
|
269
|
+
# @return [void]
|
|
270
|
+
#
|
|
271
|
+
# @api private
|
|
272
|
+
def self.associate(reflection)
|
|
273
|
+
key = reflection.options[:key] || reflection.name
|
|
274
|
+
self._reflections[key] = reflection
|
|
275
|
+
end
|
|
276
|
+
private_class_method :associate
|
|
277
|
+
|
|
278
|
+
# Define a link on a serializer.
|
|
279
|
+
# @example
|
|
280
|
+
# link(:self) { resource_url(object) }
|
|
281
|
+
# @example
|
|
282
|
+
# link(:self) { "http://example.com/resource/#{object.id}" }
|
|
283
|
+
# @example
|
|
284
|
+
# link :resource, "http://example.com/resource"
|
|
285
|
+
# @example
|
|
286
|
+
# link(:callback, if: :internal?), { "http://example.com/callback" }
|
|
287
|
+
#
|
|
288
|
+
def self.link(name, *args, &block)
|
|
289
|
+
options = args.extract_options!
|
|
290
|
+
# For compatibility with the use case of passing link directly as string argument
|
|
291
|
+
# without block, we are creating a wrapping block
|
|
292
|
+
_links[name] = Link.new(name, options, block || ->(_serializer) { args.first })
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# Set the JSON API meta attribute of a serializer.
|
|
296
|
+
# @example
|
|
297
|
+
# class AdminAuthorSerializer < ActiveModel::Serializer
|
|
298
|
+
# meta { stuff: 'value' }
|
|
299
|
+
# @example
|
|
300
|
+
# meta do
|
|
301
|
+
# { comment_count: object.comments.count }
|
|
302
|
+
# end
|
|
303
|
+
def self.meta(value = nil, &block)
|
|
304
|
+
self._meta = block || value
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# Set the JSON API type of a serializer.
|
|
308
|
+
# @example
|
|
309
|
+
# class AdminAuthorSerializer < ActiveModel::Serializer
|
|
310
|
+
# type 'authors'
|
|
311
|
+
def self.type(type)
|
|
312
|
+
self._type = type && type.to_s
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
# END SERIALIZER MACROS
|
|
316
|
+
|
|
317
|
+
attr_accessor :object, :root, :scope
|
|
318
|
+
|
|
319
|
+
# `scope_name` is set as :current_user by default in the controller.
|
|
320
|
+
# If the instance does not have a method named `scope_name`, it
|
|
321
|
+
# defines the method so that it calls the +scope+.
|
|
322
|
+
def initialize(object, options = {})
|
|
323
|
+
self.object = object
|
|
324
|
+
self.instance_options = options
|
|
325
|
+
self.root = instance_options[:root]
|
|
326
|
+
self.scope = instance_options[:scope]
|
|
327
|
+
|
|
328
|
+
return if !(scope_name = instance_options[:scope_name]) || respond_to?(scope_name)
|
|
329
|
+
|
|
330
|
+
define_singleton_method scope_name, -> { scope }
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
def success?
|
|
334
|
+
true
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
# Return the +attributes+ of +object+ as presented
|
|
338
|
+
# by the serializer.
|
|
339
|
+
def attributes(requested_attrs = nil, reload = false)
|
|
340
|
+
@attributes = nil if reload
|
|
341
|
+
@attributes ||= self.class._attributes_data.each_with_object({}) do |(key, attr), hash|
|
|
342
|
+
next if attr.excluded?(self)
|
|
343
|
+
next unless requested_attrs.nil? || requested_attrs.include?(key)
|
|
344
|
+
hash[key] = attr.value(self)
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# @param [JSONAPI::IncludeDirective] include_directive (defaults to the
|
|
349
|
+
# +default_include_directive+ config value when not provided)
|
|
350
|
+
# @return [Enumerator<Association>]
|
|
351
|
+
def associations(include_directive = ActiveModelSerializers.default_include_directive, include_slice = nil)
|
|
352
|
+
include_slice ||= include_directive
|
|
353
|
+
return Enumerator.new {} unless object
|
|
354
|
+
|
|
355
|
+
Enumerator.new do |y|
|
|
356
|
+
(self.instance_reflections ||= self.class._reflections.deep_dup).each do |key, reflection|
|
|
357
|
+
next if reflection.excluded?(self)
|
|
358
|
+
next unless include_directive.key?(key)
|
|
359
|
+
|
|
360
|
+
association = reflection.build_association(self, instance_options, include_slice)
|
|
361
|
+
y.yield association
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
# @return [Hash] containing the attributes and first level
|
|
367
|
+
# associations, similar to how ActiveModel::Serializers::JSON is used
|
|
368
|
+
# in ActiveRecord::Base.
|
|
369
|
+
def serializable_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance)
|
|
370
|
+
adapter_options ||= {}
|
|
371
|
+
options[:include_directive] ||= ActiveModel::Serializer.include_directive_from_options(adapter_options)
|
|
372
|
+
if (fieldset = adapter_options[:fieldset])
|
|
373
|
+
options[:fields] = fieldset.fields_for(json_key)
|
|
374
|
+
end
|
|
375
|
+
resource = attributes_hash(adapter_options, options, adapter_instance)
|
|
376
|
+
relationships = associations_hash(adapter_options, options, adapter_instance)
|
|
377
|
+
resource.merge(relationships)
|
|
378
|
+
end
|
|
379
|
+
alias to_hash serializable_hash
|
|
380
|
+
alias to_h serializable_hash
|
|
381
|
+
|
|
382
|
+
# @see #serializable_hash
|
|
383
|
+
def as_json(adapter_opts = nil)
|
|
384
|
+
serializable_hash(adapter_opts)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
# Used by adapter as resource root.
|
|
388
|
+
def json_key
|
|
389
|
+
root || _type ||
|
|
390
|
+
begin
|
|
391
|
+
object.class.model_name.to_s.underscore
|
|
392
|
+
rescue ArgumentError
|
|
393
|
+
'anonymous_object'
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
def read_attribute_for_serialization(attr)
|
|
398
|
+
if respond_to?(attr)
|
|
399
|
+
send(attr)
|
|
400
|
+
else
|
|
401
|
+
object.read_attribute_for_serialization(attr)
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
# @api private
|
|
406
|
+
def attributes_hash(_adapter_options, options, adapter_instance)
|
|
407
|
+
if self.class.cache_enabled?
|
|
408
|
+
fetch_attributes(options[:fields], options[:cached_attributes] || {}, adapter_instance)
|
|
409
|
+
elsif self.class.fragment_cache_enabled?
|
|
410
|
+
fetch_attributes_fragment(adapter_instance, options[:cached_attributes] || {})
|
|
411
|
+
else
|
|
412
|
+
attributes(options[:fields], true)
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
# @api private
|
|
417
|
+
def associations_hash(adapter_options, options, adapter_instance)
|
|
418
|
+
include_directive = options.fetch(:include_directive)
|
|
419
|
+
include_slice = options[:include_slice]
|
|
420
|
+
associations(include_directive, include_slice).each_with_object({}) do |association, relationships|
|
|
421
|
+
adapter_opts = adapter_options.merge(include_directive: include_directive[association.key], adapter_instance: adapter_instance)
|
|
422
|
+
relationships[association.key] = association.serializable_hash(adapter_opts, adapter_instance)
|
|
423
|
+
end
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
protected
|
|
427
|
+
|
|
428
|
+
attr_accessor :instance_options, :instance_reflections
|
|
429
|
+
end
|
|
430
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveModelSerializers
|
|
4
|
+
module Adapter
|
|
5
|
+
class Attributes < Base
|
|
6
|
+
def initialize(*)
|
|
7
|
+
super
|
|
8
|
+
instance_options[:fieldset] ||= ActiveModel::Serializer::Fieldset.new(fields_to_fieldset(instance_options.delete(:fields)))
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def serializable_hash(options = nil)
|
|
12
|
+
options = serialization_options(options.dup)
|
|
13
|
+
options[:fields] ||= instance_options[:fields]
|
|
14
|
+
serialized_hash = serializer.serializable_hash(instance_options, options, self)
|
|
15
|
+
|
|
16
|
+
self.class.transform_key_casing!(serialized_hash, instance_options)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def fields_to_fieldset(fields)
|
|
22
|
+
return fields if fields.nil?
|
|
23
|
+
resource_fields = []
|
|
24
|
+
relationship_fields = {}
|
|
25
|
+
fields.each do |field|
|
|
26
|
+
case field
|
|
27
|
+
when Symbol, String then resource_fields << field
|
|
28
|
+
when Hash then relationship_fields.merge!(field)
|
|
29
|
+
else fail ArgumentError, "Unknown conversion of fields to fieldset: '#{field.inspect}' in '#{fields.inspect}'"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
relationship_fields.merge!(serializer.json_key.to_sym => resource_fields)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'case_transform'
|
|
4
|
+
|
|
5
|
+
module ActiveModelSerializers
|
|
6
|
+
module Adapter
|
|
7
|
+
class Base
|
|
8
|
+
# Automatically register adapters when subclassing
|
|
9
|
+
def self.inherited(subclass)
|
|
10
|
+
ActiveModelSerializers::Adapter.register(subclass)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Sets the default transform for the adapter.
|
|
14
|
+
#
|
|
15
|
+
# @return [Symbol] the default transform for the adapter
|
|
16
|
+
def self.default_key_transform
|
|
17
|
+
:unaltered
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Determines the transform to use in order of precedence:
|
|
21
|
+
# adapter option, global config, adapter default.
|
|
22
|
+
#
|
|
23
|
+
# @param options [Object]
|
|
24
|
+
# @return [Symbol] the transform to use
|
|
25
|
+
def self.transform(options)
|
|
26
|
+
return options[:key_transform] if options && options[:key_transform]
|
|
27
|
+
ActiveModelSerializers.config.key_transform || default_key_transform
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Transforms the casing of the supplied value.
|
|
31
|
+
#
|
|
32
|
+
# @param value [Object] the value to be transformed
|
|
33
|
+
# @param options [Object] serializable resource options
|
|
34
|
+
# @return [Symbol] the default transform for the adapter
|
|
35
|
+
def self.transform_key_casing!(value, options)
|
|
36
|
+
CaseTransform.send(transform(options), value)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.cache_key
|
|
40
|
+
@cache_key ||= ActiveModelSerializers::Adapter.registered_name(self)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.fragment_cache(cached_hash, non_cached_hash)
|
|
44
|
+
non_cached_hash.merge cached_hash
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
attr_reader :serializer, :instance_options
|
|
48
|
+
|
|
49
|
+
def initialize(serializer, options = {})
|
|
50
|
+
@serializer = serializer
|
|
51
|
+
@instance_options = options
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Subclasses that implement this method must first call
|
|
55
|
+
# options = serialization_options(options)
|
|
56
|
+
def serializable_hash(_options = nil)
|
|
57
|
+
fail NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def as_json(options = nil)
|
|
61
|
+
serializable_hash(options)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def cache_key
|
|
65
|
+
self.class.cache_key
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def fragment_cache(cached_hash, non_cached_hash)
|
|
69
|
+
self.class.fragment_cache(cached_hash, non_cached_hash)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
# see https://github.com/rails-api/active_model_serializers/pull/965
|
|
75
|
+
# When <tt>options</tt> is +nil+, sets it to +{}+
|
|
76
|
+
def serialization_options(options)
|
|
77
|
+
options ||= {} # rubocop:disable Lint/UselessAssignment
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def root
|
|
81
|
+
serializer.json_key.to_sym if serializer.json_key
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveModelSerializers
|
|
4
|
+
module Adapter
|
|
5
|
+
class Json < Base
|
|
6
|
+
def serializable_hash(options = nil)
|
|
7
|
+
options = serialization_options(options)
|
|
8
|
+
serialized_hash = { root => Attributes.new(serializer, instance_options).serializable_hash(options) }
|
|
9
|
+
serialized_hash[meta_key] = meta unless meta.blank?
|
|
10
|
+
|
|
11
|
+
self.class.transform_key_casing!(serialized_hash, instance_options)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def meta
|
|
15
|
+
instance_options.fetch(:meta, nil)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def meta_key
|
|
19
|
+
instance_options.fetch(:meta_key, 'meta'.freeze)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|