rest_framework 0.5.5 → 0.6.0
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/VERSION +1 -1
- data/lib/rest_framework/controller_mixins/base.rb +47 -33
- data/lib/rest_framework/controller_mixins/models.rb +41 -32
- data/lib/rest_framework/filters.rb +9 -8
- data/lib/rest_framework/routers.rb +1 -1
- data/lib/rest_framework/serializers.rb +59 -26
- data/lib/rest_framework/utils.rb +6 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 365696e92f267b3c3547bc6fed9ad2cfcbc1a3cc769ee7128332cc469a534eec
|
4
|
+
data.tar.gz: bde678de3e2c11847f3777b057b5d267f75185c23a997fe704acaab6a36ad23d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 527ffee7ac29d26d0405c6ff6dba94c2d5d7e8ba505b2c6f42860fb67d782fc2b180ddaeb462947b918b84818fd30633a8290bde5d2558ced238b5a28bd9eab8
|
7
|
+
data.tar.gz: 6d56d27874e79beea8ce627fc85b0841e3a2d1cc864a7664a07ef54279216e8da80f13061ed07f3761c1da9ae570906387331c21f946c9bef102adab2bb56b6c
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
@@ -45,6 +45,7 @@ module RESTFramework::BaseControllerMixin
|
|
45
45
|
page_query_param: "page",
|
46
46
|
page_size_query_param: "page_size",
|
47
47
|
max_page_size: nil,
|
48
|
+
rescue_unknown_format_with: :json,
|
48
49
|
serializer_class: nil,
|
49
50
|
serialize_to_json: true,
|
50
51
|
serialize_to_xml: true,
|
@@ -145,42 +146,55 @@ module RESTFramework::BaseControllerMixin
|
|
145
146
|
raise RESTFramework::NilPassedToAPIResponseError
|
146
147
|
end
|
147
148
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
format.json {
|
154
|
-
jkwargs = kwargs.merge(json_kwargs)
|
155
|
-
render(json: payload, layout: false, **jkwargs)
|
156
|
-
} if self.class.serialize_to_json
|
157
|
-
format.xml {
|
158
|
-
xkwargs = kwargs.merge(xml_kwargs)
|
159
|
-
render(xml: payload, layout: false, **xkwargs)
|
160
|
-
} if self.class.serialize_to_xml
|
161
|
-
# TODO: possibly support more formats here if supported?
|
162
|
-
end
|
163
|
-
format.html {
|
164
|
-
@payload = payload
|
149
|
+
# Flag to track if we had to rescue unknown format.
|
150
|
+
already_rescued_unknown_format = false
|
151
|
+
|
152
|
+
begin
|
153
|
+
respond_to do |format|
|
165
154
|
if payload == ""
|
166
|
-
|
167
|
-
|
155
|
+
format.json { head(:no_content) } if self.class.serialize_to_json
|
156
|
+
format.xml { head(:no_content) } if self.class.serialize_to_xml
|
168
157
|
else
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
rescue ActionView::MissingTemplate # fallback to rest_framework layout
|
179
|
-
hkwargs[:layout] = "rest_framework"
|
180
|
-
hkwargs[:html] = ""
|
181
|
-
render(**hkwargs)
|
158
|
+
format.json {
|
159
|
+
jkwargs = kwargs.merge(json_kwargs)
|
160
|
+
render(json: payload, layout: false, **jkwargs)
|
161
|
+
} if self.class.serialize_to_json
|
162
|
+
format.xml {
|
163
|
+
xkwargs = kwargs.merge(xml_kwargs)
|
164
|
+
render(xml: payload, layout: false, **xkwargs)
|
165
|
+
} if self.class.serialize_to_xml
|
166
|
+
# TODO: possibly support more formats here if supported?
|
182
167
|
end
|
183
|
-
|
168
|
+
format.html {
|
169
|
+
@payload = payload
|
170
|
+
if payload == ""
|
171
|
+
@json_payload = "" if self.class.serialize_to_json
|
172
|
+
@xml_payload = "" if self.class.serialize_to_xml
|
173
|
+
else
|
174
|
+
@json_payload = payload.to_json if self.class.serialize_to_json
|
175
|
+
@xml_payload = payload.to_xml if self.class.serialize_to_xml
|
176
|
+
end
|
177
|
+
@template_logo_text ||= "Rails REST Framework"
|
178
|
+
@title ||= self.controller_name.camelize
|
179
|
+
@route_groups ||= RESTFramework::Utils.get_routes(Rails.application.routes, request)
|
180
|
+
hkwargs = kwargs.merge(html_kwargs)
|
181
|
+
begin
|
182
|
+
render(**hkwargs)
|
183
|
+
rescue ActionView::MissingTemplate # fallback to rest_framework layout
|
184
|
+
hkwargs[:layout] = "rest_framework"
|
185
|
+
hkwargs[:html] = ""
|
186
|
+
render(**hkwargs)
|
187
|
+
end
|
188
|
+
}
|
189
|
+
end
|
190
|
+
rescue ActionController::UnknownFormat
|
191
|
+
if !already_rescued_unknown_format && rescue_format = self.class.rescue_unknown_format_with
|
192
|
+
request.format = rescue_format
|
193
|
+
already_rescued_unknown_format = true
|
194
|
+
retry
|
195
|
+
else
|
196
|
+
raise
|
197
|
+
end
|
184
198
|
end
|
185
199
|
end
|
186
200
|
end
|
@@ -59,7 +59,7 @@ module RESTFramework::BaseModelControllerMixin
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def _get_specific_action_config(action_config_key, generic_config_key)
|
62
|
-
action_config = self.class.send(action_config_key) || {}
|
62
|
+
action_config = self.class.send(action_config_key)&.with_indifferent_access || {}
|
63
63
|
action = self.action_name&.to_sym
|
64
64
|
|
65
65
|
# Index action should use :list serializer if :index is not provided.
|
@@ -69,37 +69,40 @@ module RESTFramework::BaseModelControllerMixin
|
|
69
69
|
end
|
70
70
|
|
71
71
|
# Get a list of fields for the current action.
|
72
|
-
def get_fields
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
72
|
+
def get_fields(fallback: true)
|
73
|
+
action_fields = _get_specific_action_config(:action_fields, :fields)
|
74
|
+
|
75
|
+
# Typically we want to fallback to either the DB dolumns or an empty array.
|
76
|
+
if fallback
|
77
|
+
action_fields ||= self.get_model&.column_names || []
|
78
|
+
end
|
79
|
+
|
80
|
+
return action_fields
|
78
81
|
end
|
79
82
|
|
80
83
|
# Get a list of find_by fields for the current action.
|
81
84
|
def get_find_by_fields
|
82
|
-
return self.class.find_by_fields
|
85
|
+
return self.class.find_by_fields || self.get_fields
|
83
86
|
end
|
84
87
|
|
85
88
|
# Get a list of find_by fields for the current action.
|
86
89
|
def get_filterset_fields
|
87
|
-
return self.class.filterset_fields
|
90
|
+
return self.class.filterset_fields || self.get_fields
|
88
91
|
end
|
89
92
|
|
90
93
|
# Get a list of ordering fields for the current action.
|
91
94
|
def get_ordering_fields
|
92
|
-
return self.class.ordering_fields
|
95
|
+
return self.class.ordering_fields || self.get_fields
|
93
96
|
end
|
94
97
|
|
95
98
|
# Get a list of search fields for the current action.
|
96
99
|
def get_search_fields
|
97
|
-
return self.class.search_fields
|
100
|
+
return self.class.search_fields || self.get_fields
|
98
101
|
end
|
99
102
|
|
100
103
|
# Get a list of parameters allowed for the current action.
|
101
104
|
def get_allowed_parameters
|
102
|
-
return _get_specific_action_config(:allowed_action_parameters, :allowed_parameters)
|
105
|
+
return _get_specific_action_config(:allowed_action_parameters, :allowed_parameters)
|
103
106
|
end
|
104
107
|
|
105
108
|
# Helper to get the configured serializer class, or `NativeSerializer` as a default.
|
@@ -117,7 +120,8 @@ module RESTFramework::BaseModelControllerMixin
|
|
117
120
|
# Filter the request body for keys in current action's allowed_parameters/fields config.
|
118
121
|
def get_body_params
|
119
122
|
return @_get_body_params ||= begin
|
120
|
-
fields
|
123
|
+
# Map fields to strings because body keys will be string.
|
124
|
+
fields = (self.get_allowed_parameters || self.get_fields).map(&:to_s)
|
121
125
|
|
122
126
|
# Filter the request body.
|
123
127
|
body_params = request.request_parameters.select { |p| fields.include?(p) }
|
@@ -137,7 +141,7 @@ module RESTFramework::BaseModelControllerMixin
|
|
137
141
|
end
|
138
142
|
|
139
143
|
# Filter fields in exclude_body_fields.
|
140
|
-
(self.class.exclude_body_fields || []).each { |f| body_params.delete(f
|
144
|
+
(self.class.exclude_body_fields || []).each { |f| body_params.delete(f) }
|
141
145
|
|
142
146
|
body_params
|
143
147
|
end
|
@@ -181,8 +185,13 @@ module RESTFramework::BaseModelControllerMixin
|
|
181
185
|
|
182
186
|
# Get a single record by primary key or another column, if allowed.
|
183
187
|
def get_record
|
188
|
+
# Cache the result.
|
189
|
+
return @_get_record if @_get_record
|
190
|
+
|
184
191
|
recordset = self.get_recordset
|
185
|
-
|
192
|
+
|
193
|
+
# Map find_by fields to strings because query param value is a string.
|
194
|
+
find_by_fields = self.get_find_by_fields.map(&:to_s)
|
186
195
|
find_by_key = self.get_model.primary_key
|
187
196
|
|
188
197
|
# Find by another column if it's permitted.
|
@@ -196,18 +205,18 @@ module RESTFramework::BaseModelControllerMixin
|
|
196
205
|
end
|
197
206
|
|
198
207
|
# Return the record. Route key is always :id by Rails convention.
|
199
|
-
return recordset.find_by!(find_by_key => params[:id])
|
208
|
+
return @_get_record = recordset.find_by!(find_by_key => params[:id])
|
200
209
|
end
|
201
210
|
end
|
202
211
|
|
203
212
|
# Mixin for listing records.
|
204
213
|
module RESTFramework::ListModelMixin
|
205
214
|
def index
|
206
|
-
api_response(self.
|
215
|
+
api_response(self.index!)
|
207
216
|
end
|
208
217
|
|
209
|
-
def
|
210
|
-
@records
|
218
|
+
def index!
|
219
|
+
@records ||= self.get_filtered_data(self.get_recordset)
|
211
220
|
|
212
221
|
# Handle pagination, if enabled.
|
213
222
|
if self.class.paginator_class
|
@@ -224,11 +233,11 @@ end
|
|
224
233
|
# Mixin for showing records.
|
225
234
|
module RESTFramework::ShowModelMixin
|
226
235
|
def show
|
227
|
-
api_response(self.
|
236
|
+
api_response(self.show!)
|
228
237
|
end
|
229
238
|
|
230
|
-
def
|
231
|
-
@record
|
239
|
+
def show!
|
240
|
+
@record ||= self.get_record
|
232
241
|
return self.get_serializer_class.new(@record, controller: self).serialize
|
233
242
|
end
|
234
243
|
end
|
@@ -236,16 +245,16 @@ end
|
|
236
245
|
# Mixin for creating records.
|
237
246
|
module RESTFramework::CreateModelMixin
|
238
247
|
def create
|
239
|
-
api_response(self.
|
248
|
+
api_response(self.create!)
|
240
249
|
end
|
241
250
|
|
242
|
-
def
|
251
|
+
def create!
|
243
252
|
if self.get_recordset.respond_to?(:create!) && self.create_from_recordset
|
244
253
|
# Create with any properties inherited from the recordset.
|
245
|
-
@record
|
254
|
+
@record ||= self.get_recordset.create!(self.get_create_params)
|
246
255
|
else
|
247
256
|
# Otherwise, perform a "bare" create.
|
248
|
-
@record
|
257
|
+
@record ||= self.get_model.create!(self.get_create_params)
|
249
258
|
end
|
250
259
|
|
251
260
|
return self.get_serializer_class.new(@record, controller: self).serialize
|
@@ -255,11 +264,11 @@ end
|
|
255
264
|
# Mixin for updating records.
|
256
265
|
module RESTFramework::UpdateModelMixin
|
257
266
|
def update
|
258
|
-
api_response(self.
|
267
|
+
api_response(self.update!)
|
259
268
|
end
|
260
269
|
|
261
|
-
def
|
262
|
-
@record
|
270
|
+
def update!
|
271
|
+
@record ||= self.get_record
|
263
272
|
@record.update!(self.get_update_params)
|
264
273
|
return self.get_serializer_class.new(@record, controller: self).serialize
|
265
274
|
end
|
@@ -268,12 +277,12 @@ end
|
|
268
277
|
# Mixin for destroying records.
|
269
278
|
module RESTFramework::DestroyModelMixin
|
270
279
|
def destroy
|
271
|
-
self.
|
280
|
+
self.destroy!
|
272
281
|
api_response("")
|
273
282
|
end
|
274
283
|
|
275
|
-
def
|
276
|
-
@record
|
284
|
+
def destroy!
|
285
|
+
@record ||= self.get_record
|
277
286
|
@record.destroy!
|
278
287
|
end
|
279
288
|
end
|
@@ -13,15 +13,15 @@ end
|
|
13
13
|
class RESTFramework::ModelFilter < RESTFramework::BaseFilter
|
14
14
|
# Filter params for keys allowed by the current action's filterset_fields/fields config.
|
15
15
|
def _get_filter_params
|
16
|
-
fields
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
# Map filterset fields to strings because query parameter keys are strings.
|
17
|
+
fields = @controller.get_filterset_fields.map(&:to_s)
|
18
|
+
|
19
|
+
return @controller.request.query_parameters.select { |p, _| fields.include?(p) }
|
20
20
|
end
|
21
21
|
|
22
22
|
# Filter data according to the request query parameters.
|
23
23
|
def get_filtered_data(data)
|
24
|
-
filter_params = self._get_filter_params
|
24
|
+
filter_params = self._get_filter_params.symbolize_keys
|
25
25
|
unless filter_params.blank?
|
26
26
|
return data.where(**filter_params)
|
27
27
|
end
|
@@ -36,11 +36,12 @@ class RESTFramework::ModelOrderingFilter < RESTFramework::BaseFilter
|
|
36
36
|
def _get_ordering
|
37
37
|
return nil if @controller.class.ordering_query_param.blank?
|
38
38
|
|
39
|
-
ordering_fields
|
39
|
+
# Ensure ordering_fields are strings since the split param will be strings.
|
40
|
+
ordering_fields = @controller.get_ordering_fields.map(&:to_s)
|
40
41
|
order_string = @controller.params[@controller.class.ordering_query_param]
|
41
42
|
|
42
43
|
unless order_string.blank?
|
43
|
-
ordering = {}
|
44
|
+
ordering = {}.with_indifferent_access
|
44
45
|
order_string.split(",").each do |field|
|
45
46
|
if field[0] == "-"
|
46
47
|
column = field[1..-1]
|
@@ -50,7 +51,7 @@ class RESTFramework::ModelOrderingFilter < RESTFramework::BaseFilter
|
|
50
51
|
direction = :asc
|
51
52
|
end
|
52
53
|
if column.in?(ordering_fields)
|
53
|
-
ordering[column
|
54
|
+
ordering[column] = direction
|
54
55
|
end
|
55
56
|
end
|
56
57
|
return ordering
|
@@ -6,7 +6,7 @@ module ActionDispatch::Routing
|
|
6
6
|
# Internal interface to get the controller class from the name and current scope.
|
7
7
|
def _get_controller_class(name, pluralize: true, fallback_reverse_pluralization: true)
|
8
8
|
# Get class name.
|
9
|
-
name = name.to_s.camelize #
|
9
|
+
name = name.to_s.camelize # Camelize to leave plural names plural.
|
10
10
|
name = name.pluralize if pluralize
|
11
11
|
if name == name.pluralize
|
12
12
|
name_reverse = name.singularize
|
@@ -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
|
-
|
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(
|
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
|
-
#
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
33
|
-
|
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
|
-
#
|
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
|
-
# If the config wasn't determined, build a serializer config from
|
201
|
-
fields = @controller.get_fields if @controller
|
215
|
+
# If the config wasn't determined, build a serializer config from controller fields.
|
216
|
+
fields = @controller.get_fields(fallback: false) 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
|
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(
|
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|
|
257
|
+
return @object.map { |r| self._serialize(r, config, serializer_methods) }
|
225
258
|
end
|
226
259
|
|
227
|
-
return @object
|
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.
|
data/lib/rest_framework/utils.rb
CHANGED
@@ -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.
|
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
|
-
|
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
|
-
|
81
|
-
|
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[:
|
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.
|
4
|
+
version: 0.6.0
|
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-
|
11
|
+
date: 2022-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|