active_model_serializers 0.10.0.rc2 → 0.10.0.rc3
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/.gitignore +2 -0
- data/.rubocop.yml +82 -0
- data/.rubocop_todo.yml +315 -0
- data/.simplecov +99 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +9 -3
- data/Gemfile +39 -8
- data/README.md +55 -31
- data/Rakefile +29 -2
- data/active_model_serializers.gemspec +37 -13
- data/appveyor.yml +25 -0
- data/docs/README.md +29 -0
- data/docs/general/adapters.md +110 -0
- data/docs/general/configuration_options.md +11 -0
- data/docs/general/getting_started.md +73 -0
- data/docs/howto/add_pagination_links.md +112 -0
- data/docs/howto/add_root_key.md +51 -0
- data/docs/howto/outside_controller_use.md +42 -0
- data/lib/action_controller/serialization.rb +24 -33
- data/lib/active_model/serializable_resource.rb +70 -0
- data/lib/active_model/serializer.rb +50 -131
- data/lib/active_model/serializer/adapter.rb +84 -21
- data/lib/active_model/serializer/adapter/flatten_json.rb +9 -9
- data/lib/active_model/serializer/adapter/fragment_cache.rb +10 -13
- data/lib/active_model/serializer/adapter/json.rb +25 -28
- data/lib/active_model/serializer/adapter/json/fragment_cache.rb +2 -12
- data/lib/active_model/serializer/adapter/json_api.rb +100 -98
- data/lib/active_model/serializer/adapter/json_api/fragment_cache.rb +4 -14
- data/lib/active_model/serializer/adapter/json_api/pagination_links.rb +50 -0
- data/lib/active_model/serializer/adapter/null.rb +2 -8
- data/lib/active_model/serializer/array_serializer.rb +22 -17
- data/lib/active_model/serializer/association.rb +20 -0
- data/lib/active_model/serializer/associations.rb +97 -0
- data/lib/active_model/serializer/belongs_to_reflection.rb +10 -0
- data/lib/active_model/serializer/collection_reflection.rb +7 -0
- data/lib/active_model/serializer/configuration.rb +1 -0
- data/lib/active_model/serializer/fieldset.rb +7 -7
- data/lib/active_model/serializer/has_many_reflection.rb +10 -0
- data/lib/active_model/serializer/has_one_reflection.rb +10 -0
- data/lib/active_model/serializer/lint.rb +129 -0
- data/lib/active_model/serializer/railtie.rb +7 -0
- data/lib/active_model/serializer/reflection.rb +74 -0
- data/lib/active_model/serializer/singular_reflection.rb +7 -0
- data/lib/active_model/serializer/utils.rb +35 -0
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model_serializers.rb +28 -14
- data/lib/generators/serializer/serializer_generator.rb +7 -7
- data/lib/generators/serializer/templates/{serializer.rb → serializer.rb.erb} +2 -2
- data/lib/tasks/rubocop.rake +0 -0
- data/test/action_controller/adapter_selector_test.rb +3 -3
- data/test/action_controller/explicit_serializer_test.rb +9 -9
- data/test/action_controller/json_api/linked_test.rb +179 -0
- data/test/action_controller/json_api/pagination_test.rb +116 -0
- data/test/action_controller/serialization_scope_name_test.rb +10 -6
- data/test/action_controller/serialization_test.rb +149 -112
- data/test/active_record_test.rb +9 -0
- data/test/adapter/fragment_cache_test.rb +11 -1
- data/test/adapter/json/belongs_to_test.rb +4 -5
- data/test/adapter/json/collection_test.rb +30 -21
- data/test/adapter/json/has_many_test.rb +20 -9
- data/test/adapter/json_api/belongs_to_test.rb +38 -38
- data/test/adapter/json_api/collection_test.rb +22 -23
- data/test/adapter/json_api/has_many_embed_ids_test.rb +2 -2
- data/test/adapter/json_api/has_many_explicit_serializer_test.rb +4 -4
- data/test/adapter/json_api/has_many_test.rb +54 -19
- data/test/adapter/json_api/has_one_test.rb +28 -8
- data/test/adapter/json_api/json_api_test.rb +37 -0
- data/test/adapter/json_api/linked_test.rb +75 -75
- data/test/adapter/json_api/pagination_links_test.rb +115 -0
- data/test/adapter/json_api/resource_type_config_test.rb +59 -0
- data/test/adapter/json_test.rb +18 -5
- data/test/adapter_test.rb +10 -11
- data/test/array_serializer_test.rb +63 -5
- data/test/capture_warnings.rb +65 -0
- data/test/fixtures/active_record.rb +56 -0
- data/test/fixtures/poro.rb +60 -29
- data/test/generators/scaffold_controller_generator_test.rb +1 -2
- data/test/generators/serializer_generator_test.rb +17 -12
- data/test/lint_test.rb +37 -0
- data/test/logger_test.rb +18 -0
- data/test/poro_test.rb +9 -0
- data/test/serializable_resource_test.rb +27 -0
- data/test/serializers/adapter_for_test.rb +123 -3
- data/test/serializers/association_macros_test.rb +36 -0
- data/test/serializers/associations_test.rb +70 -47
- data/test/serializers/attribute_test.rb +28 -4
- data/test/serializers/attributes_test.rb +8 -14
- data/test/serializers/cache_test.rb +58 -31
- data/test/serializers/fieldset_test.rb +3 -4
- data/test/serializers/meta_test.rb +42 -28
- data/test/serializers/root_test.rb +21 -0
- data/test/serializers/serializer_for_test.rb +1 -1
- data/test/support/rails_app.rb +21 -0
- data/test/support/serialization_testing.rb +13 -0
- data/test/support/simplecov.rb +6 -0
- data/test/support/stream_capture.rb +50 -0
- data/test/support/test_case.rb +5 -0
- data/test/test_helper.rb +41 -29
- data/test/utils/include_args_to_hash_test.rb +79 -0
- metadata +123 -17
- data/test/action_controller/json_api_linked_test.rb +0 -179
- data/test/action_controller/rescue_from_test.rb +0 -32
- data/test/serializers/urls_test.rb +0 -26
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'set'
|
2
|
+
module ActiveModel
|
3
|
+
class SerializableResource
|
4
|
+
ADAPTER_OPTION_KEYS = Set.new([:include, :fields, :adapter])
|
5
|
+
|
6
|
+
# Primary interface to composing a resource with a serializer and adapter.
|
7
|
+
# @return the serializable_resource, ready for #as_json/#to_json/#serializable_hash.
|
8
|
+
def initialize(resource, options = {})
|
9
|
+
@resource = resource
|
10
|
+
@adapter_opts, @serializer_opts =
|
11
|
+
options.partition { |k, _| ADAPTER_OPTION_KEYS.include? k }.map { |h| Hash[h] }
|
12
|
+
end
|
13
|
+
|
14
|
+
delegate :serializable_hash, :as_json, :to_json, to: :adapter
|
15
|
+
|
16
|
+
def serialization_scope=(scope)
|
17
|
+
serializer_opts[:scope] = scope
|
18
|
+
end
|
19
|
+
|
20
|
+
def serialization_scope
|
21
|
+
serializer_opts[:scope]
|
22
|
+
end
|
23
|
+
|
24
|
+
def serialization_scope_name=(scope_name)
|
25
|
+
serializer_opts[:scope_name] = scope_name
|
26
|
+
end
|
27
|
+
|
28
|
+
def adapter
|
29
|
+
@adapter ||= ActiveModel::Serializer::Adapter.create(serializer_instance, adapter_opts)
|
30
|
+
end
|
31
|
+
alias_method :adapter_instance, :adapter
|
32
|
+
|
33
|
+
def serializer_instance
|
34
|
+
@serializer_instance ||= serializer.new(resource, serializer_opts)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Get serializer either explicitly :serializer or implicitly from resource
|
38
|
+
# Remove :serializer key from serializer_opts
|
39
|
+
# Replace :serializer key with :each_serializer if present
|
40
|
+
def serializer
|
41
|
+
@serializer ||=
|
42
|
+
begin
|
43
|
+
@serializer = serializer_opts.delete(:serializer)
|
44
|
+
@serializer ||= ActiveModel::Serializer.serializer_for(resource)
|
45
|
+
|
46
|
+
if serializer_opts.key?(:each_serializer)
|
47
|
+
serializer_opts[:serializer] = serializer_opts.delete(:each_serializer)
|
48
|
+
end
|
49
|
+
@serializer
|
50
|
+
end
|
51
|
+
end
|
52
|
+
alias_method :serializer_class, :serializer
|
53
|
+
|
54
|
+
# True when no explicit adapter given, or explicit appear is truthy (non-nil)
|
55
|
+
# False when explicit adapter is falsy (nil or false)
|
56
|
+
def use_adapter?
|
57
|
+
!(adapter_opts.key?(:adapter) && !adapter_opts[:adapter])
|
58
|
+
end
|
59
|
+
|
60
|
+
def serializer?
|
61
|
+
use_adapter? && !!(serializer)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
ActiveModelSerializers.silence_warnings do
|
67
|
+
attr_reader :resource, :adapter_opts, :serializer_opts
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -3,16 +3,35 @@ require 'thread_safe'
|
|
3
3
|
module ActiveModel
|
4
4
|
class Serializer
|
5
5
|
extend ActiveSupport::Autoload
|
6
|
+
|
6
7
|
autoload :Configuration
|
7
8
|
autoload :ArraySerializer
|
8
9
|
autoload :Adapter
|
10
|
+
autoload :Lint
|
11
|
+
autoload :Associations
|
12
|
+
autoload :Fieldset
|
13
|
+
autoload :Utils
|
9
14
|
include Configuration
|
15
|
+
include Associations
|
16
|
+
|
17
|
+
# Matches
|
18
|
+
# "c:/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb:1:in `<top (required)>'"
|
19
|
+
# AND
|
20
|
+
# "/c/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb:1:in `<top (required)>'"
|
21
|
+
# AS
|
22
|
+
# c/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb
|
23
|
+
CALLER_FILE = /
|
24
|
+
\A # start of string
|
25
|
+
\S+ # one or more non-spaces
|
26
|
+
(?= # stop previous match when
|
27
|
+
:\d+ # a colon is followed by one or more digits
|
28
|
+
:in # followed by a colon followed by in
|
29
|
+
)
|
30
|
+
/x
|
10
31
|
|
11
32
|
class << self
|
12
33
|
attr_accessor :_attributes
|
13
34
|
attr_accessor :_attributes_keys
|
14
|
-
attr_accessor :_associations
|
15
|
-
attr_accessor :_urls
|
16
35
|
attr_accessor :_cache
|
17
36
|
attr_accessor :_fragmented
|
18
37
|
attr_accessor :_cache_key
|
@@ -23,12 +42,10 @@ module ActiveModel
|
|
23
42
|
end
|
24
43
|
|
25
44
|
def self.inherited(base)
|
26
|
-
base._attributes = self._attributes.try(:dup)
|
45
|
+
base._attributes = self._attributes.try(:dup) || []
|
27
46
|
base._attributes_keys = self._attributes_keys.try(:dup) || {}
|
28
|
-
base.
|
29
|
-
|
30
|
-
serializer_file = File.open(caller.first[/^[^:]+/])
|
31
|
-
base._cache_digest = Digest::MD5.hexdigest(serializer_file.read)
|
47
|
+
base._cache_digest = digest_caller_file(caller.first)
|
48
|
+
super
|
32
49
|
end
|
33
50
|
|
34
51
|
def self.attributes(*attrs)
|
@@ -45,11 +62,14 @@ module ActiveModel
|
|
45
62
|
|
46
63
|
def self.attribute(attr, options = {})
|
47
64
|
key = options.fetch(:key, attr)
|
48
|
-
@_attributes_keys[attr] = {key: key} if key != attr
|
65
|
+
@_attributes_keys[attr] = { key: key } if key != attr
|
49
66
|
@_attributes << key unless @_attributes.include?(key)
|
50
|
-
|
51
|
-
|
52
|
-
|
67
|
+
|
68
|
+
ActiveModelSerializers.silence_warnings do
|
69
|
+
define_method key do
|
70
|
+
object.read_attribute_for_serialization(attr)
|
71
|
+
end unless (key != :id && method_defined?(key)) || _fragmented.respond_to?(attr)
|
72
|
+
end
|
53
73
|
end
|
54
74
|
|
55
75
|
def self.fragmented(serializer)
|
@@ -58,91 +78,26 @@ module ActiveModel
|
|
58
78
|
|
59
79
|
# Enables a serializer to be automatically cached
|
60
80
|
def self.cache(options = {})
|
61
|
-
@_cache
|
62
|
-
@_cache_key
|
63
|
-
@_cache_only
|
64
|
-
@_cache_except
|
81
|
+
@_cache = ActionController::Base.cache_store if Rails.configuration.action_controller.perform_caching
|
82
|
+
@_cache_key = options.delete(:key)
|
83
|
+
@_cache_only = options.delete(:only)
|
84
|
+
@_cache_except = options.delete(:except)
|
65
85
|
@_cache_options = (options.empty?) ? nil : options
|
66
86
|
end
|
67
87
|
|
68
|
-
# Defines an association in the object should be rendered.
|
69
|
-
#
|
70
|
-
# The serializer object should implement the association name
|
71
|
-
# as a method which should return an array when invoked. If a method
|
72
|
-
# with the association name does not exist, the association name is
|
73
|
-
# dispatched to the serialized object.
|
74
|
-
def self.has_many(*attrs)
|
75
|
-
associate(:has_many, attrs)
|
76
|
-
end
|
77
|
-
|
78
|
-
# Defines an association in the object that should be rendered.
|
79
|
-
#
|
80
|
-
# The serializer object should implement the association name
|
81
|
-
# as a method which should return an object when invoked. If a method
|
82
|
-
# with the association name does not exist, the association name is
|
83
|
-
# dispatched to the serialized object.
|
84
|
-
def self.belongs_to(*attrs)
|
85
|
-
associate(:belongs_to, attrs)
|
86
|
-
end
|
87
|
-
|
88
|
-
# Defines an association in the object should be rendered.
|
89
|
-
#
|
90
|
-
# The serializer object should implement the association name
|
91
|
-
# as a method which should return an object when invoked. If a method
|
92
|
-
# with the association name does not exist, the association name is
|
93
|
-
# dispatched to the serialized object.
|
94
|
-
def self.has_one(*attrs)
|
95
|
-
associate(:has_one, attrs)
|
96
|
-
end
|
97
|
-
|
98
|
-
def self.associate(type, attrs) #:nodoc:
|
99
|
-
options = attrs.extract_options!
|
100
|
-
self._associations = _associations.dup
|
101
|
-
|
102
|
-
attrs.each do |attr|
|
103
|
-
unless method_defined?(attr)
|
104
|
-
define_method attr do
|
105
|
-
object.send attr
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
self._associations[attr] = {type: type, association_options: options}
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def self.url(attr)
|
114
|
-
@_urls.push attr
|
115
|
-
end
|
116
|
-
|
117
|
-
def self.urls(*attrs)
|
118
|
-
@_urls.concat attrs
|
119
|
-
end
|
120
|
-
|
121
88
|
def self.serializer_for(resource, options = {})
|
122
89
|
if resource.respond_to?(:serializer_class)
|
123
90
|
resource.serializer_class
|
124
91
|
elsif resource.respond_to?(:to_ary)
|
125
92
|
config.array_serializer
|
126
93
|
else
|
127
|
-
options
|
128
|
-
.fetch(:association_options, {})
|
129
|
-
.fetch(:serializer, get_serializer_for(resource.class))
|
94
|
+
options.fetch(:serializer, get_serializer_for(resource.class))
|
130
95
|
end
|
131
96
|
end
|
132
97
|
|
98
|
+
# @see ActiveModel::Serializer::Adapter.lookup
|
133
99
|
def self.adapter
|
134
|
-
|
135
|
-
when Symbol
|
136
|
-
ActiveModel::Serializer::Adapter.adapter_class(config.adapter)
|
137
|
-
when Class
|
138
|
-
config.adapter
|
139
|
-
end
|
140
|
-
unless adapter_class
|
141
|
-
valid_adapters = Adapter.constants.map { |klass| ":#{klass.to_s.downcase}" }
|
142
|
-
raise ArgumentError, "Unknown adapter: #{config.adapter}. Valid adapters are: #{valid_adapters}"
|
143
|
-
end
|
144
|
-
|
145
|
-
adapter_class
|
100
|
+
ActiveModel::Serializer::Adapter.lookup(config.adapter)
|
146
101
|
end
|
147
102
|
|
148
103
|
def self.root_name
|
@@ -152,12 +107,12 @@ module ActiveModel
|
|
152
107
|
attr_accessor :object, :root, :meta, :meta_key, :scope
|
153
108
|
|
154
109
|
def initialize(object, options = {})
|
155
|
-
@object
|
156
|
-
@options
|
157
|
-
@root
|
158
|
-
@meta
|
159
|
-
@meta_key
|
160
|
-
@scope
|
110
|
+
@object = object
|
111
|
+
@options = options
|
112
|
+
@root = options[:root]
|
113
|
+
@meta = options[:meta]
|
114
|
+
@meta_key = options[:meta_key]
|
115
|
+
@scope = options[:scope]
|
161
116
|
|
162
117
|
scope_name = options[:scope_name]
|
163
118
|
if scope_name && !respond_to?(scope_name)
|
@@ -168,15 +123,7 @@ module ActiveModel
|
|
168
123
|
end
|
169
124
|
|
170
125
|
def json_key
|
171
|
-
|
172
|
-
end
|
173
|
-
|
174
|
-
def id
|
175
|
-
object.id if object
|
176
|
-
end
|
177
|
-
|
178
|
-
def type
|
179
|
-
object.class.model_name.plural
|
126
|
+
@root || object.class.model_name.to_s.underscore
|
180
127
|
end
|
181
128
|
|
182
129
|
def attributes(options = {})
|
@@ -187,8 +134,6 @@ module ActiveModel
|
|
187
134
|
self.class._attributes.dup
|
188
135
|
end
|
189
136
|
|
190
|
-
attributes += options[:required_fields] if options[:required_fields]
|
191
|
-
|
192
137
|
attributes.each_with_object({}) do |name, hash|
|
193
138
|
unless self.class._fragmented
|
194
139
|
hash[name] = send(name)
|
@@ -198,40 +143,15 @@ module ActiveModel
|
|
198
143
|
end
|
199
144
|
end
|
200
145
|
|
201
|
-
def each_association(&block)
|
202
|
-
self.class._associations.dup.each do |name, association_options|
|
203
|
-
next unless object
|
204
|
-
association_value = send(name)
|
205
|
-
|
206
|
-
serializer_class = ActiveModel::Serializer.serializer_for(association_value, association_options)
|
207
|
-
|
208
|
-
if serializer_class
|
209
|
-
serializer = serializer_class.new(
|
210
|
-
association_value,
|
211
|
-
options.except(:serializer).merge(serializer_from_options(association_options))
|
212
|
-
)
|
213
|
-
elsif !association_value.nil? && !association_value.instance_of?(Object)
|
214
|
-
association_options[:association_options][:virtual_value] = association_value
|
215
|
-
end
|
216
|
-
|
217
|
-
if block_given?
|
218
|
-
block.call(name, serializer, association_options[:association_options])
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
def serializer_from_options(options)
|
224
|
-
opts = {}
|
225
|
-
serializer = options.fetch(:association_options, {}).fetch(:serializer, nil)
|
226
|
-
opts[:serializer] = serializer if serializer
|
227
|
-
opts
|
228
|
-
end
|
229
|
-
|
230
146
|
def self.serializers_cache
|
231
147
|
@serializers_cache ||= ThreadSafe::Cache.new
|
232
148
|
end
|
233
149
|
|
234
|
-
|
150
|
+
def self.digest_caller_file(caller_line)
|
151
|
+
serializer_file_path = caller_line[CALLER_FILE]
|
152
|
+
serializer_file_contents = IO.read(serializer_file_path)
|
153
|
+
Digest::MD5.hexdigest(serializer_file_contents)
|
154
|
+
end
|
235
155
|
|
236
156
|
attr_reader :options
|
237
157
|
|
@@ -247,6 +167,5 @@ module ActiveModel
|
|
247
167
|
end
|
248
168
|
end
|
249
169
|
end
|
250
|
-
|
251
170
|
end
|
252
171
|
end
|
@@ -1,13 +1,84 @@
|
|
1
|
-
require 'active_model/serializer/adapter/fragment_cache'
|
2
|
-
|
3
1
|
module ActiveModel
|
4
2
|
class Serializer
|
5
3
|
class Adapter
|
4
|
+
UnknownAdapterError = Class.new(ArgumentError)
|
5
|
+
ADAPTER_MAP = {}
|
6
|
+
private_constant :ADAPTER_MAP if defined?(private_constant)
|
6
7
|
extend ActiveSupport::Autoload
|
8
|
+
autoload :FragmentCache
|
7
9
|
autoload :Json
|
8
|
-
autoload :FlattenJson
|
9
|
-
autoload :Null
|
10
10
|
autoload :JsonApi
|
11
|
+
autoload :Null
|
12
|
+
autoload :FlattenJson
|
13
|
+
|
14
|
+
def self.create(resource, options = {})
|
15
|
+
override = options.delete(:adapter)
|
16
|
+
klass = override ? adapter_class(override) : ActiveModel::Serializer.adapter
|
17
|
+
klass.new(resource, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @see ActiveModel::Serializer::Adapter.lookup
|
21
|
+
def self.adapter_class(adapter)
|
22
|
+
ActiveModel::Serializer::Adapter.lookup(adapter)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Only the Adapter class has these methods.
|
26
|
+
# None of the sublasses have them.
|
27
|
+
class << ActiveModel::Serializer::Adapter
|
28
|
+
# @return Hash<adapter_name, adapter_class>
|
29
|
+
def adapter_map
|
30
|
+
ADAPTER_MAP
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [Array<Symbol>] list of adapter names
|
34
|
+
def adapters
|
35
|
+
adapter_map.keys.sort
|
36
|
+
end
|
37
|
+
|
38
|
+
# Adds an adapter 'klass' with 'name' to the 'adapter_map'
|
39
|
+
# Names are stringified and underscored
|
40
|
+
# @param [Symbol, String] name of the registered adapter
|
41
|
+
# @param [Class] klass - adapter class itself
|
42
|
+
# @example
|
43
|
+
# AMS::Adapter.register(:my_adapter, MyAdapter)
|
44
|
+
def register(name, klass)
|
45
|
+
adapter_map.update(name.to_s.underscore => klass)
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
# @param adapter [String, Symbol, Class] name to fetch adapter by
|
50
|
+
# @return [ActiveModel::Serializer::Adapter] subclass of Adapter
|
51
|
+
# @raise [UnknownAdapterError]
|
52
|
+
def lookup(adapter)
|
53
|
+
# 1. return if is a class
|
54
|
+
return adapter if adapter.is_a?(Class)
|
55
|
+
adapter_name = adapter.to_s.underscore
|
56
|
+
# 2. return if registered
|
57
|
+
adapter_map.fetch(adapter_name) {
|
58
|
+
# 3. try to find adapter class from environment
|
59
|
+
adapter_class = find_by_name(adapter_name)
|
60
|
+
register(adapter_name, adapter_class)
|
61
|
+
adapter_class
|
62
|
+
}
|
63
|
+
rescue NameError, ArgumentError => e
|
64
|
+
failure_message =
|
65
|
+
"NameError: #{e.message}. Unknown adapter: #{adapter.inspect}. Valid adapters are: #{adapters}"
|
66
|
+
raise UnknownAdapterError, failure_message, e.backtrace
|
67
|
+
end
|
68
|
+
|
69
|
+
# @api private
|
70
|
+
def find_by_name(adapter_name)
|
71
|
+
adapter_name = adapter_name.to_s.classify.tr('API', 'Api')
|
72
|
+
ActiveModel::Serializer::Adapter.const_get(adapter_name.to_sym) or # rubocop:disable Style/AndOr
|
73
|
+
fail UnknownAdapterError
|
74
|
+
end
|
75
|
+
private :find_by_name
|
76
|
+
end
|
77
|
+
|
78
|
+
# Automatically register adapters when subclassing
|
79
|
+
def self.inherited(subclass)
|
80
|
+
ActiveModel::Serializer::Adapter.register(subclass.to_s.demodulize, subclass)
|
81
|
+
end
|
11
82
|
|
12
83
|
attr_reader :serializer
|
13
84
|
|
@@ -16,33 +87,23 @@ module ActiveModel
|
|
16
87
|
@options = options
|
17
88
|
end
|
18
89
|
|
19
|
-
def serializable_hash(options =
|
90
|
+
def serializable_hash(options = nil)
|
20
91
|
raise NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
|
21
92
|
end
|
22
93
|
|
23
|
-
def as_json(options =
|
94
|
+
def as_json(options = nil)
|
24
95
|
hash = serializable_hash(options)
|
25
|
-
include_meta(hash)
|
96
|
+
include_meta(hash)
|
26
97
|
hash
|
27
98
|
end
|
28
99
|
|
29
|
-
def self.create(resource, options = {})
|
30
|
-
override = options.delete(:adapter)
|
31
|
-
klass = override ? adapter_class(override) : ActiveModel::Serializer.adapter
|
32
|
-
klass.new(resource, options)
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.adapter_class(adapter)
|
36
|
-
"ActiveModel::Serializer::Adapter::#{adapter.to_s.classify}".safe_constantize
|
37
|
-
end
|
38
|
-
|
39
100
|
def fragment_cache(*args)
|
40
101
|
raise NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.'
|
41
102
|
end
|
42
103
|
|
43
104
|
private
|
44
105
|
|
45
|
-
|
106
|
+
def cache_check(serializer)
|
46
107
|
@cached_serializer = serializer
|
47
108
|
@klass = @cached_serializer.class
|
48
109
|
if is_cached?
|
@@ -68,11 +129,13 @@ module ActiveModel
|
|
68
129
|
parts = []
|
69
130
|
parts << object_cache_key
|
70
131
|
parts << @klass._cache_digest unless @klass._cache_options && @klass._cache_options[:skip_digest]
|
71
|
-
parts.join(
|
132
|
+
parts.join('/')
|
72
133
|
end
|
73
134
|
|
74
135
|
def object_cache_key
|
75
|
-
|
136
|
+
object_time_safe = @cached_serializer.object.updated_at
|
137
|
+
object_time_safe = object_time_safe.strftime('%Y%m%d%H%M%S%9N') if object_time_safe.respond_to?(:strftime)
|
138
|
+
(@klass._cache_key) ? "#{@klass._cache_key}/#{@cached_serializer.object.id}-#{object_time_safe}" : @cached_serializer.object.cache_key
|
76
139
|
end
|
77
140
|
|
78
141
|
def meta
|
@@ -80,7 +143,7 @@ module ActiveModel
|
|
80
143
|
end
|
81
144
|
|
82
145
|
def meta_key
|
83
|
-
serializer.meta_key ||
|
146
|
+
serializer.meta_key || 'meta'
|
84
147
|
end
|
85
148
|
|
86
149
|
def root
|