rest_framework 0.5.4 → 0.5.7
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 +33 -29
- data/lib/rest_framework/filters.rb +9 -8
- data/lib/rest_framework/routers.rb +1 -1
- data/lib/rest_framework/serializers.rb +57 -22
- data/lib/rest_framework/utils.rb +8 -7
- 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: a9e50f091ca2fab796992252f39a700ab1c22ad89b50953654240ac5273cd7ac
|
4
|
+
data.tar.gz: ed46ccce3fb8986f207f5b8e996f1a9577e58834f70fcc7de0c36a3e54b8f65f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed76863c305eb92f712affbb0d43b1470c518f933226a86c60983690edf5846faadc7dca0278d1075ed903d6637b45c4eeff1788e00ef130ec49457f94dba4f4
|
7
|
+
data.tar.gz: 16b12ff971d7201669d0114804e8664dc641065c771c4cb34ba1ac21899f1fd14fd396d363f76619a58dba67688b88e35ae69b34be80e4975b6f94cfe6760c67
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.7
|
@@ -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.
|
@@ -71,35 +71,33 @@ module RESTFramework::BaseModelControllerMixin
|
|
71
71
|
# Get a list of fields for the current action.
|
72
72
|
def get_fields
|
73
73
|
return (
|
74
|
-
_get_specific_action_config(:action_fields, :fields)&.
|
75
|
-
self.get_model&.column_names ||
|
76
|
-
[]
|
74
|
+
_get_specific_action_config(:action_fields, :fields) || self.get_model&.column_names || []
|
77
75
|
)
|
78
76
|
end
|
79
77
|
|
80
78
|
# Get a list of find_by fields for the current action.
|
81
79
|
def get_find_by_fields
|
82
|
-
return self.class.find_by_fields
|
80
|
+
return self.class.find_by_fields || self.get_fields
|
83
81
|
end
|
84
82
|
|
85
83
|
# Get a list of find_by fields for the current action.
|
86
84
|
def get_filterset_fields
|
87
|
-
return self.class.filterset_fields
|
85
|
+
return self.class.filterset_fields || self.get_fields
|
88
86
|
end
|
89
87
|
|
90
88
|
# Get a list of ordering fields for the current action.
|
91
89
|
def get_ordering_fields
|
92
|
-
return self.class.ordering_fields
|
90
|
+
return self.class.ordering_fields || self.get_fields
|
93
91
|
end
|
94
92
|
|
95
93
|
# Get a list of search fields for the current action.
|
96
94
|
def get_search_fields
|
97
|
-
return self.class.search_fields
|
95
|
+
return self.class.search_fields || self.get_fields
|
98
96
|
end
|
99
97
|
|
100
98
|
# Get a list of parameters allowed for the current action.
|
101
99
|
def get_allowed_parameters
|
102
|
-
return _get_specific_action_config(:allowed_action_parameters, :allowed_parameters)
|
100
|
+
return _get_specific_action_config(:allowed_action_parameters, :allowed_parameters)
|
103
101
|
end
|
104
102
|
|
105
103
|
# Helper to get the configured serializer class, or `NativeSerializer` as a default.
|
@@ -117,7 +115,8 @@ module RESTFramework::BaseModelControllerMixin
|
|
117
115
|
# Filter the request body for keys in current action's allowed_parameters/fields config.
|
118
116
|
def get_body_params
|
119
117
|
return @_get_body_params ||= begin
|
120
|
-
fields
|
118
|
+
# Map fields to strings because body keys will be string.
|
119
|
+
fields = (self.get_allowed_parameters || self.get_fields).map(&:to_s)
|
121
120
|
|
122
121
|
# Filter the request body.
|
123
122
|
body_params = request.request_parameters.select { |p| fields.include?(p) }
|
@@ -137,7 +136,7 @@ module RESTFramework::BaseModelControllerMixin
|
|
137
136
|
end
|
138
137
|
|
139
138
|
# Filter fields in exclude_body_fields.
|
140
|
-
(self.class.exclude_body_fields || []).each { |f| body_params.delete(f
|
139
|
+
(self.class.exclude_body_fields || []).each { |f| body_params.delete(f) }
|
141
140
|
|
142
141
|
body_params
|
143
142
|
end
|
@@ -181,8 +180,13 @@ module RESTFramework::BaseModelControllerMixin
|
|
181
180
|
|
182
181
|
# Get a single record by primary key or another column, if allowed.
|
183
182
|
def get_record
|
183
|
+
# Cache the result.
|
184
|
+
return @_get_record if @_get_record
|
185
|
+
|
184
186
|
recordset = self.get_recordset
|
185
|
-
|
187
|
+
|
188
|
+
# Map find_by fields to strings because query param value is a string.
|
189
|
+
find_by_fields = self.get_find_by_fields.map(&:to_s)
|
186
190
|
find_by_key = self.get_model.primary_key
|
187
191
|
|
188
192
|
# Find by another column if it's permitted.
|
@@ -196,18 +200,18 @@ module RESTFramework::BaseModelControllerMixin
|
|
196
200
|
end
|
197
201
|
|
198
202
|
# Return the record. Route key is always :id by Rails convention.
|
199
|
-
return recordset.find_by!(find_by_key => params[:id])
|
203
|
+
return @_get_record = recordset.find_by!(find_by_key => params[:id])
|
200
204
|
end
|
201
205
|
end
|
202
206
|
|
203
207
|
# Mixin for listing records.
|
204
208
|
module RESTFramework::ListModelMixin
|
205
209
|
def index
|
206
|
-
api_response(self.
|
210
|
+
api_response(self.index!)
|
207
211
|
end
|
208
212
|
|
209
|
-
def
|
210
|
-
@records
|
213
|
+
def index!
|
214
|
+
@records ||= self.get_filtered_data(self.get_recordset)
|
211
215
|
|
212
216
|
# Handle pagination, if enabled.
|
213
217
|
if self.class.paginator_class
|
@@ -224,11 +228,11 @@ end
|
|
224
228
|
# Mixin for showing records.
|
225
229
|
module RESTFramework::ShowModelMixin
|
226
230
|
def show
|
227
|
-
api_response(self.
|
231
|
+
api_response(self.show!)
|
228
232
|
end
|
229
233
|
|
230
|
-
def
|
231
|
-
@record
|
234
|
+
def show!
|
235
|
+
@record ||= self.get_record
|
232
236
|
return self.get_serializer_class.new(@record, controller: self).serialize
|
233
237
|
end
|
234
238
|
end
|
@@ -236,16 +240,16 @@ end
|
|
236
240
|
# Mixin for creating records.
|
237
241
|
module RESTFramework::CreateModelMixin
|
238
242
|
def create
|
239
|
-
api_response(self.
|
243
|
+
api_response(self.create!)
|
240
244
|
end
|
241
245
|
|
242
|
-
def
|
246
|
+
def create!
|
243
247
|
if self.get_recordset.respond_to?(:create!) && self.create_from_recordset
|
244
248
|
# Create with any properties inherited from the recordset.
|
245
|
-
@record
|
249
|
+
@record ||= self.get_recordset.create!(self.get_create_params)
|
246
250
|
else
|
247
251
|
# Otherwise, perform a "bare" create.
|
248
|
-
@record
|
252
|
+
@record ||= self.get_model.create!(self.get_create_params)
|
249
253
|
end
|
250
254
|
|
251
255
|
return self.get_serializer_class.new(@record, controller: self).serialize
|
@@ -255,11 +259,11 @@ end
|
|
255
259
|
# Mixin for updating records.
|
256
260
|
module RESTFramework::UpdateModelMixin
|
257
261
|
def update
|
258
|
-
api_response(self.
|
262
|
+
api_response(self.update!)
|
259
263
|
end
|
260
264
|
|
261
|
-
def
|
262
|
-
@record
|
265
|
+
def update!
|
266
|
+
@record ||= self.get_record
|
263
267
|
@record.update!(self.get_update_params)
|
264
268
|
return self.get_serializer_class.new(@record, controller: self).serialize
|
265
269
|
end
|
@@ -268,12 +272,12 @@ end
|
|
268
272
|
# Mixin for destroying records.
|
269
273
|
module RESTFramework::DestroyModelMixin
|
270
274
|
def destroy
|
271
|
-
self.
|
275
|
+
self.destroy!
|
272
276
|
api_response("")
|
273
277
|
end
|
274
278
|
|
275
|
-
def
|
276
|
-
@record
|
279
|
+
def destroy!
|
280
|
+
@record ||= self.get_record
|
277
281
|
@record.destroy!
|
278
282
|
end
|
279
283
|
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,21 +1,38 @@
|
|
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
|
-
# Synonym for `
|
17
|
-
def serializable_hash(
|
18
|
-
return self.serialize(
|
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 []
|
19
36
|
end
|
20
37
|
end
|
21
38
|
|
@@ -27,8 +44,9 @@ class RESTFramework::NativeSerializer < RESTFramework::BaseSerializer
|
|
27
44
|
class_attribute :plural_config
|
28
45
|
class_attribute :action_config
|
29
46
|
|
30
|
-
|
31
|
-
|
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)
|
32
50
|
|
33
51
|
if many.nil?
|
34
52
|
# Determine if we are dealing with many objects or just one.
|
@@ -146,10 +164,7 @@ class RESTFramework::NativeSerializer < RESTFramework::BaseSerializer
|
|
146
164
|
except = except.split(",").map(&:strip).map(&:to_sym)
|
147
165
|
|
148
166
|
unless except.empty?
|
149
|
-
#
|
150
|
-
cfg = cfg.deep_dup
|
151
|
-
|
152
|
-
# Filter `only`, `except` (additive), `include`, and `methods`.
|
167
|
+
# Filter `only`, `except` (additive), `include`, `methods`, and `serializer_methods`.
|
153
168
|
if cfg[:only]
|
154
169
|
cfg[:only] = self.class.filter_subcfg(cfg[:only], except: except)
|
155
170
|
else
|
@@ -157,14 +172,14 @@ class RESTFramework::NativeSerializer < RESTFramework::BaseSerializer
|
|
157
172
|
end
|
158
173
|
cfg[:include] = self.class.filter_subcfg(cfg[:include], except: except)
|
159
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
|
+
)
|
160
178
|
end
|
161
179
|
elsif only_param && only = @controller.request.query_parameters[only_param].presence
|
162
180
|
only = only.split(",").map(&:strip).map(&:to_sym)
|
163
181
|
|
164
182
|
unless only.empty?
|
165
|
-
# Duplicate the cfg to avoid mutating class state.
|
166
|
-
cfg = cfg.deep_dup
|
167
|
-
|
168
183
|
# For the `except` part of the serializer, we need to append any columns not in `only`.
|
169
184
|
model = @controller.get_model
|
170
185
|
except_cols = model&.column_names&.map(&:to_sym)&.reject { |c| c.in?(only) }
|
@@ -177,27 +192,31 @@ class RESTFramework::NativeSerializer < RESTFramework::BaseSerializer
|
|
177
192
|
end
|
178
193
|
cfg[:include] = self.class.filter_subcfg(cfg[:include], only: only)
|
179
194
|
cfg[:methods] = self.class.filter_subcfg(cfg[:methods], only: only)
|
195
|
+
cfg[:serializer_methods] = self.class.filter_subcfg(cfg[:serializer_methods], only: only)
|
180
196
|
end
|
181
197
|
end
|
182
198
|
|
183
199
|
return cfg
|
184
200
|
end
|
185
201
|
|
186
|
-
# 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.
|
187
204
|
def _get_raw_serializer_config
|
188
205
|
# Return a locally defined serializer config if one is defined.
|
189
206
|
if local_config = self.get_local_native_serializer_config
|
190
|
-
return local_config
|
207
|
+
return local_config.deep_dup
|
191
208
|
end
|
192
209
|
|
193
210
|
# Return a serializer config if one is defined on the controller.
|
194
211
|
if serializer_config = self.get_controller_native_serializer_config
|
195
|
-
return serializer_config
|
212
|
+
return serializer_config.deep_dup
|
196
213
|
end
|
197
214
|
|
198
215
|
# If the config wasn't determined, build a serializer config from model fields.
|
199
216
|
fields = @controller.get_fields if @controller
|
200
217
|
if fields
|
218
|
+
fields = fields.deep_dup
|
219
|
+
|
201
220
|
if @model
|
202
221
|
columns, methods = fields.partition { |f| f.in?(@model.column_names) }
|
203
222
|
else
|
@@ -214,15 +233,31 @@ class RESTFramework::NativeSerializer < RESTFramework::BaseSerializer
|
|
214
233
|
|
215
234
|
# Get a configuration passable to `serializable_hash` for the object, filtered if required.
|
216
235
|
def get_serializer_config
|
217
|
-
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
|
+
)
|
218
250
|
end
|
219
251
|
|
220
|
-
def serialize(
|
252
|
+
def serialize(*args)
|
253
|
+
config = self.get_serializer_config
|
254
|
+
serializer_methods = config.delete(:serializer_methods)
|
255
|
+
|
221
256
|
if @object.respond_to?(:to_ary)
|
222
|
-
return @object.map { |r|
|
257
|
+
return @object.map { |r| self._serialize(r, config, serializer_methods) }
|
223
258
|
end
|
224
259
|
|
225
|
-
return @object
|
260
|
+
return self._serialize(@object, config, serializer_methods)
|
226
261
|
end
|
227
262
|
|
228
263
|
# Allow a serializer instance to be used as a hash directly in a nested serializer config.
|
data/lib/rest_framework/utils.rb
CHANGED
@@ -9,7 +9,7 @@ module RESTFramework::Utils
|
|
9
9
|
path = k
|
10
10
|
|
11
11
|
# Convert structure to path/methods/kwargs.
|
12
|
-
if v.is_a?(Hash) #
|
12
|
+
if v.is_a?(Hash) # Allow kwargs to be used to define path differently from the key.
|
13
13
|
v = v.symbolize_keys
|
14
14
|
|
15
15
|
# Ensure methods is an array.
|
@@ -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,
|
@@ -87,8 +88,8 @@ module RESTFramework::Utils
|
|
87
88
|
}
|
88
89
|
}.select { |r|
|
89
90
|
(
|
90
|
-
r[:subdomain] == request.subdomain.presence &&
|
91
|
-
r[:
|
91
|
+
(!r[:subdomain] || r[:subdomain] == request.subdomain.presence) &&
|
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.
|
4
|
+
version: 0.5.7
|
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-06-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|