rest_framework 0.5.5 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 237449a323a14356f20e47cd2cbab3591aa749fc7e6f43bc06587995ff1041dc
4
- data.tar.gz: 98ff07d840fca2fd09ab608a08a2814c5fe17c9ded1a7476c176941224c75e53
3
+ metadata.gz: a4a0533297190fd34ec007578f495d67ef19e3e02b7b495b8be004dd2180f6b2
4
+ data.tar.gz: 07f5478177e47bae6476c42587b10b698a862bbcfa762497a7bd11ebb5cf324e
5
5
  SHA512:
6
- metadata.gz: 5219df61d409aeda527a61508694cf5b46dba856f03db4d7a2432d8d208a89eb5ccaccee2d7da88472d5b2735a77b235127d903497b9bb3fb19b740f2eb5df05
7
- data.tar.gz: afbc3a40c39d312a0ebaaade7ce8c1d4d00b99fbd3da4168b0e9706d63d2fb59aa6d0f1d56cc4832a6eca10b783f43c20a2f9cf8d1015ef817293ba5852a7a62
6
+ metadata.gz: d971192a3c797b69e9e7982f2f7e381b7fa2784db39e592c56f3640683985424e40a52e28a0ff503f0c22ad2b0cedbd828ba5b4461e354abe36d5d9e8c01c370
7
+ data.tar.gz: 22f0d3779328a0c5dccb382674d44dfea4a5cffea92b96614366d9cbfa570ce436ea5774c13a16f524b995c54074d5ad5d979e82d081d2f012f89923f55339f6
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.5
1
+ 0.5.6
@@ -1,24 +1,39 @@
1
1
  # The base serializer defines the interface for all REST Framework serializers.
2
2
  class RESTFramework::BaseSerializer
3
+ # Add `object` accessor to be compatible with `ActiveModel::Serializer`.
3
4
  attr_accessor :object
4
5
 
5
- def initialize(object=nil, controller: nil, **kwargs)
6
+ # Accept/ignore `*args` to be compatible with the `ActiveModel::Serializer#initialize` signature.
7
+ def initialize(object=nil, *args, controller: nil, **kwargs)
6
8
  @object = object
7
9
  @controller = controller
8
10
  end
9
11
 
10
12
  # The primary interface for extracting a native Ruby types. This works both for records and
11
- # collections.
12
- def serialize(**kwargs)
13
+ # collections. We accept and ignore `*args` for compatibility with `active_model_serializers`.
14
+ def serialize(*args)
13
15
  raise NotImplementedError
14
16
  end
15
17
 
16
- # :nocov:
17
- # Synonym for `serializable_hash` or compatibility with ActiveModelSerializers.
18
- def serializable_hash(**kwargs)
19
- return self.serialize(**kwargs)
18
+ # Synonym for `serialize` for compatibility with `active_model_serializers`.
19
+ def serializable_hash(*args)
20
+ return self.serialize(*args)
21
+ end
22
+
23
+ # For compatibility with `active_model_serializers`.
24
+ def self.cache_enabled?
25
+ return false
26
+ end
27
+
28
+ # For compatibility with `active_model_serializers`.
29
+ def self.fragment_cache_enabled?
30
+ return false
31
+ end
32
+
33
+ # For compatibility with `active_model_serializers`.
34
+ def associations(*args, **kwargs)
35
+ return []
20
36
  end
21
- # :nocov:
22
37
  end
23
38
 
24
39
  # This serializer uses `.serializable_hash` to convert objects to Ruby primitives (with the
@@ -29,8 +44,9 @@ class RESTFramework::NativeSerializer < RESTFramework::BaseSerializer
29
44
  class_attribute :plural_config
30
45
  class_attribute :action_config
31
46
 
32
- def initialize(object=nil, many: nil, model: nil, **kwargs)
33
- super(object, **kwargs)
47
+ # Accept/ignore `*args` to be compatible with the `ActiveModel::Serializer#initialize` signature.
48
+ def initialize(object=nil, *args, many: nil, model: nil, **kwargs)
49
+ super(object, *args, **kwargs)
34
50
 
35
51
  if many.nil?
36
52
  # Determine if we are dealing with many objects or just one.
@@ -148,10 +164,7 @@ class RESTFramework::NativeSerializer < RESTFramework::BaseSerializer
148
164
  except = except.split(",").map(&:strip).map(&:to_sym)
149
165
 
150
166
  unless except.empty?
151
- # Duplicate the cfg to avoid mutating class state.
152
- cfg = cfg.deep_dup
153
-
154
- # Filter `only`, `except` (additive), `include`, and `methods`.
167
+ # Filter `only`, `except` (additive), `include`, `methods`, and `serializer_methods`.
155
168
  if cfg[:only]
156
169
  cfg[:only] = self.class.filter_subcfg(cfg[:only], except: except)
157
170
  else
@@ -159,14 +172,14 @@ class RESTFramework::NativeSerializer < RESTFramework::BaseSerializer
159
172
  end
160
173
  cfg[:include] = self.class.filter_subcfg(cfg[:include], except: except)
161
174
  cfg[:methods] = self.class.filter_subcfg(cfg[:methods], except: except)
175
+ cfg[:serializer_methods] = self.class.filter_subcfg(
176
+ cfg[:serializer_methods], except: except
177
+ )
162
178
  end
163
179
  elsif only_param && only = @controller.request.query_parameters[only_param].presence
164
180
  only = only.split(",").map(&:strip).map(&:to_sym)
165
181
 
166
182
  unless only.empty?
167
- # Duplicate the cfg to avoid mutating class state.
168
- cfg = cfg.deep_dup
169
-
170
183
  # For the `except` part of the serializer, we need to append any columns not in `only`.
171
184
  model = @controller.get_model
172
185
  except_cols = model&.column_names&.map(&:to_sym)&.reject { |c| c.in?(only) }
@@ -179,27 +192,31 @@ class RESTFramework::NativeSerializer < RESTFramework::BaseSerializer
179
192
  end
180
193
  cfg[:include] = self.class.filter_subcfg(cfg[:include], only: only)
181
194
  cfg[:methods] = self.class.filter_subcfg(cfg[:methods], only: only)
195
+ cfg[:serializer_methods] = self.class.filter_subcfg(cfg[:serializer_methods], only: only)
182
196
  end
183
197
  end
184
198
 
185
199
  return cfg
186
200
  end
187
201
 
188
- # Get the raw serializer config.
202
+ # Get the raw serializer config. Use `deep_dup` on any class mutables (array, hash, etc) to avoid
203
+ # mutating class state.
189
204
  def _get_raw_serializer_config
190
205
  # Return a locally defined serializer config if one is defined.
191
206
  if local_config = self.get_local_native_serializer_config
192
- return local_config
207
+ return local_config.deep_dup
193
208
  end
194
209
 
195
210
  # Return a serializer config if one is defined on the controller.
196
211
  if serializer_config = self.get_controller_native_serializer_config
197
- return serializer_config
212
+ return serializer_config.deep_dup
198
213
  end
199
214
 
200
215
  # If the config wasn't determined, build a serializer config from model fields.
201
216
  fields = @controller.get_fields if @controller
202
217
  if fields
218
+ fields = fields.deep_dup
219
+
203
220
  if @model
204
221
  columns, methods = fields.partition { |f| f.in?(@model.column_names) }
205
222
  else
@@ -216,15 +233,31 @@ class RESTFramework::NativeSerializer < RESTFramework::BaseSerializer
216
233
 
217
234
  # Get a configuration passable to `serializable_hash` for the object, filtered if required.
218
235
  def get_serializer_config
219
- return @_serializer_config ||= filter_except(self._get_raw_serializer_config)
236
+ return filter_except(self._get_raw_serializer_config)
237
+ end
238
+
239
+ # Internal helper to serialize a single record and merge results of `serializer_methods`.
240
+ def _serialize(record, config, serializer_methods)
241
+ # Ensure serializer_methods is either falsy, or an array.
242
+ if serializer_methods && !serializer_methods.respond_to?(:to_ary)
243
+ serializer_methods = [serializer_methods]
244
+ end
245
+
246
+ # Merge serialized record with any serializer method results.
247
+ return record.serializable_hash(config).merge(
248
+ serializer_methods&.map { |m| [m.to_sym, self.send(m, record)] }.to_h,
249
+ )
220
250
  end
221
251
 
222
- def serialize(**kwargs)
252
+ def serialize(*args)
253
+ config = self.get_serializer_config
254
+ serializer_methods = config.delete(:serializer_methods)
255
+
223
256
  if @object.respond_to?(:to_ary)
224
- return @object.map { |r| r.serializable_hash(self.get_serializer_config) }
257
+ return @object.map { |r| self._serialize(r, config, serializer_methods) }
225
258
  end
226
259
 
227
- return @object.serializable_hash(self.get_serializer_config)
260
+ return self._serialize(@object, config, serializer_methods)
228
261
  end
229
262
 
230
263
  # Allow a serializer instance to be used as a hash directly in a nested serializer config.
@@ -49,7 +49,7 @@ module RESTFramework::Utils
49
49
 
50
50
  # Helper to normalize a path pattern by replacing URL params with generic placeholder, and
51
51
  # removing the `(.:format)` at the end.
52
- def self.normalize_path(path)
52
+ def self.comparable_path(path)
53
53
  return path.gsub("(.:format)", "").gsub(/:[0-9A-Za-z_-]+/, ":x")
54
54
  end
55
55
 
@@ -58,7 +58,7 @@ module RESTFramework::Utils
58
58
  current_route ||= self.get_request_route(application_routes, request)
59
59
  current_path = current_route.path.spec.to_s
60
60
  current_levels = current_path.count("/")
61
- current_normalized_path = self.normalize_path(current_path)
61
+ current_comparable_path = self.comparable_path(current_path)
62
62
 
63
63
  # Return routes that match our current route subdomain/pattern, grouped by controller. We
64
64
  # precompute certain properties of the route for performance.
@@ -77,8 +77,9 @@ module RESTFramework::Utils
77
77
  route: r,
78
78
  verb: r.verb,
79
79
  path: path,
80
- normalized_path: self.normalize_path(path),
81
- relative_path: path.split("/")[current_levels..]&.join("/"),
80
+ comparable_path: self.comparable_path(path),
81
+ # Starts at the number of levels in current path, and removes the `(.:format)` at the end.
82
+ relative_path: path.split("/")[current_levels..]&.join("/")&.gsub("(.:format)", ""),
82
83
  controller: r.defaults[:controller].presence,
83
84
  action: r.defaults[:action].presence,
84
85
  subdomain: r.defaults[:subdomain].presence,
@@ -88,7 +89,7 @@ module RESTFramework::Utils
88
89
  }.select { |r|
89
90
  (
90
91
  (!r[:subdomain] || r[:subdomain] == request.subdomain.presence) &&
91
- r[:normalized_path].start_with?(current_normalized_path) &&
92
+ r[:comparable_path].start_with?(current_comparable_path) &&
92
93
  r[:controller] &&
93
94
  r[:action]
94
95
  )
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest_framework
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregory N. Schmit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-15 00:00:00.000000000 Z
11
+ date: 2022-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails