rest_framework 1.0.0.beta2 → 1.0.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/README.md +32 -24
- data/VERSION +1 -1
- data/lib/rest_framework/engine.rb +6 -0
- data/lib/rest_framework/errors/nil_passed_to_render_api_error.rb +1 -1
- data/lib/rest_framework/errors/unknown_model_error.rb +1 -1
- data/lib/rest_framework/filters/ordering_filter.rb +3 -3
- data/lib/rest_framework/filters/query_filter.rb +101 -33
- data/lib/rest_framework/filters/ransack_filter.rb +1 -1
- data/lib/rest_framework/filters/search_filter.rb +3 -3
- data/lib/rest_framework/generators/controller_generator.rb +2 -2
- data/lib/rest_framework/mixins/base_controller_mixin.rb +90 -51
- data/lib/rest_framework/mixins/bulk_model_controller_mixin.rb +12 -19
- data/lib/rest_framework/mixins/model_controller_mixin.rb +95 -56
- data/lib/rest_framework/paginators/page_number_paginator.rb +6 -6
- data/lib/rest_framework/routers.rb +16 -9
- data/lib/rest_framework/serializers/active_model_serializer_adapter_factory.rb +4 -2
- data/lib/rest_framework/serializers/base_serializer.rb +7 -5
- data/lib/rest_framework/serializers/native_serializer.rb +22 -22
- data/lib/rest_framework/utils.rb +33 -47
- data/lib/rest_framework/version.rb +1 -1
- data/lib/rest_framework.rb +26 -15
- metadata +5 -5
@@ -7,7 +7,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
7
7
|
class_attribute :action_config
|
8
8
|
|
9
9
|
# Accept/ignore `*args` to be compatible with the `ActiveModel::Serializer#initialize` signature.
|
10
|
-
def initialize(object=nil, *args, many: nil, model: nil, **kwargs)
|
10
|
+
def initialize(object = nil, *args, many: nil, model: nil, **kwargs)
|
11
11
|
super(object, *args, **kwargs)
|
12
12
|
|
13
13
|
if many.nil?
|
@@ -28,7 +28,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
28
28
|
|
29
29
|
# Get controller action, if possible.
|
30
30
|
def get_action
|
31
|
-
|
31
|
+
@controller&.action_name&.to_sym
|
32
32
|
end
|
33
33
|
|
34
34
|
# Get a locally defined native serializer configuration, if one is defined.
|
@@ -47,7 +47,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
47
47
|
return self.singular_config if @many == false && self.singular_config
|
48
48
|
|
49
49
|
# Lastly, try returning the default config, or singular/plural config in that order.
|
50
|
-
|
50
|
+
self.config || self.singular_config || self.plural_config
|
51
51
|
end
|
52
52
|
|
53
53
|
# Get a native serializer configuration from the controller.
|
@@ -60,7 +60,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
60
60
|
controller_serializer = @controller.class.native_serializer_singular_config
|
61
61
|
end
|
62
62
|
|
63
|
-
|
63
|
+
controller_serializer || @controller.class.native_serializer_config
|
64
64
|
end
|
65
65
|
|
66
66
|
# Filter a single subconfig for specific keys. By default, keys from `fields` are removed from the
|
@@ -99,7 +99,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
99
99
|
subcfg = subcfg.to_sym
|
100
100
|
|
101
101
|
if add
|
102
|
-
subcfg = subcfg.in?(fields) ? fields : [subcfg, *fields]
|
102
|
+
subcfg = subcfg.in?(fields) ? fields : [ subcfg, *fields ]
|
103
103
|
elsif only
|
104
104
|
subcfg = subcfg.in?(fields) ? subcfg : []
|
105
105
|
else
|
@@ -107,7 +107,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
|
-
|
110
|
+
subcfg
|
111
111
|
end
|
112
112
|
|
113
113
|
# Filter out configuration properties based on the :except/:only query parameters.
|
@@ -153,7 +153,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
|
-
|
156
|
+
cfg
|
157
157
|
end
|
158
158
|
|
159
159
|
# Get the associations limit from the controller.
|
@@ -174,7 +174,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
174
174
|
end
|
175
175
|
end
|
176
176
|
|
177
|
-
|
177
|
+
@_get_associations_limit = limit
|
178
178
|
end
|
179
179
|
|
180
180
|
# Get a serializer configuration from the controller. `@controller` and `@model` must be set.
|
@@ -210,7 +210,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
210
210
|
sub_methods << sf
|
211
211
|
end
|
212
212
|
end
|
213
|
-
sub_config = {only: sub_columns, methods: sub_methods}
|
213
|
+
sub_config = { only: sub_columns, methods: sub_methods }
|
214
214
|
|
215
215
|
# Apply certain rules regarding collection associations.
|
216
216
|
if ref.collection?
|
@@ -257,7 +257,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
257
257
|
# ActiveStorage Integration: Define attachment serializer method.
|
258
258
|
if ref.macro == :has_one_attached
|
259
259
|
serializer_methods[f] = f
|
260
|
-
includes_map[f] = {"#{f}_attachment": :blob}
|
260
|
+
includes_map[f] = { "#{f}_attachment": :blob }
|
261
261
|
self.define_singleton_method(f) do |record|
|
262
262
|
attached = record.send(f)
|
263
263
|
next attached.attachment ? {
|
@@ -268,7 +268,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
268
268
|
end
|
269
269
|
elsif ref.macro == :has_many_attached
|
270
270
|
serializer_methods[f] = f
|
271
|
-
includes_map[f] = {"#{f}_attachments": :blob}
|
271
|
+
includes_map[f] = { "#{f}_attachments": :blob }
|
272
272
|
self.define_singleton_method(f) do |record|
|
273
273
|
# Iterating the collection yields attachment objects.
|
274
274
|
next record.send(f).map { |a|
|
@@ -288,7 +288,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
288
288
|
end
|
289
289
|
end
|
290
290
|
|
291
|
-
|
291
|
+
{
|
292
292
|
only: columns,
|
293
293
|
include: includes,
|
294
294
|
methods: methods,
|
@@ -317,24 +317,24 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
317
317
|
end
|
318
318
|
|
319
319
|
# By default, pass an empty configuration, using the default Rails serializer.
|
320
|
-
|
320
|
+
{}
|
321
321
|
end
|
322
322
|
|
323
323
|
# Get a configuration passable to `serializable_hash` for the object, filtered if required.
|
324
324
|
def get_serializer_config
|
325
|
-
|
325
|
+
self.filter_from_request(self.get_raw_serializer_config)
|
326
326
|
end
|
327
327
|
|
328
328
|
# Serialize a single record and merge results of `serializer_methods`.
|
329
329
|
def _serialize(record, config, serializer_methods)
|
330
330
|
# Ensure serializer_methods is either falsy, or a hash.
|
331
331
|
if serializer_methods && !serializer_methods.is_a?(Hash)
|
332
|
-
serializer_methods = [serializer_methods].flatten.map { |m| [m, m] }.to_h
|
332
|
+
serializer_methods = [ serializer_methods ].flatten.map { |m| [ m, m ] }.to_h
|
333
333
|
end
|
334
334
|
|
335
335
|
# Merge serialized record with any serializer method results.
|
336
|
-
|
337
|
-
serializer_methods&.map { |m, k| [k.to_sym, self.send(m, record)] }.to_h,
|
336
|
+
record.serializable_hash(config).merge(
|
337
|
+
serializer_methods&.map { |m, k| [ k.to_sym, self.send(m, record) ] }.to_h,
|
338
338
|
)
|
339
339
|
end
|
340
340
|
|
@@ -352,29 +352,29 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
352
352
|
return @object.map { |r| self._serialize(r, config, serializer_methods) }
|
353
353
|
end
|
354
354
|
|
355
|
-
|
355
|
+
self._serialize(@object, config, serializer_methods)
|
356
356
|
end
|
357
357
|
|
358
358
|
# Allow a serializer instance to be used as a hash directly in a nested serializer config.
|
359
359
|
def [](key)
|
360
360
|
@_nested_config ||= self.get_serializer_config
|
361
|
-
|
361
|
+
@_nested_config[key]
|
362
362
|
end
|
363
363
|
|
364
364
|
def []=(key, value)
|
365
365
|
@_nested_config ||= self.get_serializer_config
|
366
|
-
|
366
|
+
@_nested_config[key] = value
|
367
367
|
end
|
368
368
|
|
369
369
|
# Allow a serializer class to be used as a hash directly in a nested serializer config.
|
370
370
|
def self.[](key)
|
371
371
|
@_nested_config ||= self.new.get_serializer_config
|
372
|
-
|
372
|
+
@_nested_config[key]
|
373
373
|
end
|
374
374
|
|
375
375
|
def self.[]=(key, value)
|
376
376
|
@_nested_config ||= self.new.get_serializer_config
|
377
|
-
|
377
|
+
@_nested_config[key] = value
|
378
378
|
end
|
379
379
|
end
|
380
380
|
|
data/lib/rest_framework/utils.rb
CHANGED
@@ -1,49 +1,32 @@
|
|
1
1
|
module RESTFramework::Utils
|
2
|
-
HTTP_VERB_ORDERING = %w
|
2
|
+
HTTP_VERB_ORDERING = %w[GET POST PUT PATCH DELETE OPTIONS HEAD]
|
3
3
|
|
4
|
-
# Convert `extra_actions` hash to a consistent format: `{path:, methods:, kwargs:}`.
|
5
|
-
|
6
|
-
|
7
|
-
def self.parse_extra_actions(extra_actions, controller: nil)
|
8
|
-
return (extra_actions || {}).map { |k, v|
|
4
|
+
# Convert `extra_actions` hash to a consistent format: `{path:, methods:, metadata:, kwargs:}`.
|
5
|
+
def self.parse_extra_actions(extra_actions)
|
6
|
+
(extra_actions || {}).map { |k, v|
|
9
7
|
path = k
|
8
|
+
kwargs = {}
|
10
9
|
|
11
10
|
# Convert structure to path/methods/kwargs.
|
12
|
-
if v.is_a?(Hash)
|
11
|
+
if v.is_a?(Hash)
|
13
12
|
# Symbolize keys (which also makes a copy so we don't mutate the original).
|
14
13
|
v = v.symbolize_keys
|
15
|
-
methods = v.delete(:methods)
|
16
|
-
if v.key?(:method)
|
17
|
-
methods = v.delete(:method)
|
18
|
-
end
|
19
14
|
|
20
|
-
#
|
21
|
-
|
22
|
-
if controller && metadata&.key?(:fields)
|
23
|
-
metadata[:fields] = metadata[:fields].map { |f|
|
24
|
-
[f, {}]
|
25
|
-
}.to_h if metadata[:fields].is_a?(Array)
|
26
|
-
metadata[:fields]&.each do |field, cfg|
|
27
|
-
cfg[:label] = controller.label_for(field) unless cfg[:label]
|
28
|
-
end
|
29
|
-
end
|
15
|
+
# Cast method/methods to an array.
|
16
|
+
methods = [ v.delete(:methods), v.delete(:method) ].flatten.compact
|
30
17
|
|
31
18
|
# Override path if it's provided.
|
32
19
|
if v.key?(:path)
|
33
20
|
path = v.delete(:path)
|
34
21
|
end
|
35
22
|
|
23
|
+
# Extract metadata, if provided.
|
24
|
+
metadata = v.delete(:metadata).presence
|
25
|
+
|
36
26
|
# Pass any further kwargs to the underlying Rails interface.
|
37
|
-
kwargs = v
|
38
|
-
elsif v.is_a?(Array) && v.length == 1
|
39
|
-
methods = v[0]
|
27
|
+
kwargs = v
|
40
28
|
else
|
41
|
-
methods = v
|
42
|
-
end
|
43
|
-
|
44
|
-
# Insert action label if it's not provided.
|
45
|
-
if controller
|
46
|
-
metadata[:label] ||= controller.label_for(k)
|
29
|
+
methods = [ v ].flatten
|
47
30
|
end
|
48
31
|
|
49
32
|
next [
|
@@ -51,6 +34,7 @@ module RESTFramework::Utils
|
|
51
34
|
{
|
52
35
|
path: path,
|
53
36
|
methods: methods,
|
37
|
+
metadata: metadata,
|
54
38
|
kwargs: kwargs,
|
55
39
|
}.compact,
|
56
40
|
]
|
@@ -59,7 +43,7 @@ module RESTFramework::Utils
|
|
59
43
|
|
60
44
|
# Get actions which should be skipped for a given controller.
|
61
45
|
def self.get_skipped_builtin_actions(controller_class)
|
62
|
-
|
46
|
+
(
|
63
47
|
RESTFramework::BUILTIN_ACTIONS.keys + RESTFramework::BUILTIN_MEMBER_ACTIONS.keys
|
64
48
|
).reject do |action|
|
65
49
|
controller_class.method_defined?(action)
|
@@ -74,7 +58,7 @@ module RESTFramework::Utils
|
|
74
58
|
# Normalize a path pattern by replacing URL params with generic placeholder, and removing the
|
75
59
|
# `(.:format)` at the end.
|
76
60
|
def self.comparable_path(path)
|
77
|
-
|
61
|
+
path.gsub("(.:format)", "").gsub(/:[0-9A-Za-z_-]+/, ":x")
|
78
62
|
end
|
79
63
|
|
80
64
|
# Show routes under a controller action; used for the browsable API.
|
@@ -90,7 +74,7 @@ module RESTFramework::Utils
|
|
90
74
|
|
91
75
|
# Return routes that match our current route subdomain/pattern, grouped by controller. We
|
92
76
|
# precompute certain properties of the route for performance.
|
93
|
-
|
77
|
+
application_routes.routes.select { |r|
|
94
78
|
# We `select` first to avoid unnecessarily calculating metadata for routes we don't even want
|
95
79
|
# to show.
|
96
80
|
(r.defaults[:subdomain].blank? || r.defaults[:subdomain] == request.subdomain) &&
|
@@ -116,7 +100,7 @@ module RESTFramework::Utils
|
|
116
100
|
verb: r.verb,
|
117
101
|
path: path,
|
118
102
|
path_with_params: r.format(
|
119
|
-
r.required_parts.each_with_index.map { |p, i| [p, path_params[i]] }.to_h,
|
103
|
+
r.required_parts.each_with_index.map { |p, i| [ p, path_params[i] ] }.to_h,
|
120
104
|
),
|
121
105
|
relative_path: relative_path,
|
122
106
|
concat_path: concat_path,
|
@@ -139,17 +123,19 @@ module RESTFramework::Utils
|
|
139
123
|
]
|
140
124
|
}.group_by { |r| r[:controller] }.sort_by { |c, _r|
|
141
125
|
# Sort the controller groups by current controller first, then alphanumerically.
|
142
|
-
|
126
|
+
# Note: Use `controller_path` instead of `params[:controller]` to avoid re-raising a
|
127
|
+
# `ActionDispatch::Http::Parameters::ParseError` exception.
|
128
|
+
[ request.controller_class.controller_path == c ? 0 : 1, c ]
|
143
129
|
}.to_h
|
144
130
|
end
|
145
131
|
|
146
132
|
# Custom inflector for RESTful controllers.
|
147
|
-
def self.inflect(s, acronyms=nil)
|
133
|
+
def self.inflect(s, acronyms = nil)
|
148
134
|
acronyms&.each do |acronym|
|
149
135
|
s = s.gsub(/\b#{acronym}\b/i, acronym)
|
150
136
|
end
|
151
137
|
|
152
|
-
|
138
|
+
s
|
153
139
|
end
|
154
140
|
|
155
141
|
# Parse fields hashes.
|
@@ -167,12 +153,12 @@ module RESTFramework::Utils
|
|
167
153
|
parsed_fields -= h[:except].map(&:to_s) if h[:except]
|
168
154
|
|
169
155
|
# Warn for any unknown keys.
|
170
|
-
(h.keys - [:only, :except, :include, :exclude]).each do |k|
|
156
|
+
(h.keys - [ :only, :except, :include, :exclude ]).each do |k|
|
171
157
|
Rails.logger.warn("RRF: Unknown key in fields hash: #{k}")
|
172
158
|
end
|
173
159
|
|
174
160
|
# We should always return strings, not symbols.
|
175
|
-
|
161
|
+
parsed_fields.map(&:to_s)
|
176
162
|
end
|
177
163
|
|
178
164
|
# Get the fields for a given model, including not just columns (which includes
|
@@ -195,7 +181,7 @@ module RESTFramework::Utils
|
|
195
181
|
# Associations:
|
196
182
|
associations = model.reflections.map { |association, ref|
|
197
183
|
# Ignore associations for which we have custom integrations.
|
198
|
-
if ref.class_name.in?(%w
|
184
|
+
if ref.class_name.in?(%w[ActionText::RichText ActiveStorage::Attachment ActiveStorage::Blob])
|
199
185
|
next nil
|
200
186
|
end
|
201
187
|
|
@@ -208,29 +194,29 @@ module RESTFramework::Utils
|
|
208
194
|
next association
|
209
195
|
}.compact
|
210
196
|
|
211
|
-
|
197
|
+
base_fields + associations + atf + asf
|
212
198
|
end
|
213
199
|
|
214
200
|
# Get the sub-fields that may be serialized and filtered/ordered for a reflection.
|
215
201
|
def self.sub_fields_for(ref)
|
216
202
|
if !ref.polymorphic? && model = ref.klass
|
217
|
-
sub_fields = [model.primary_key].flatten.compact
|
203
|
+
sub_fields = [ model.primary_key ].flatten.compact
|
218
204
|
label_fields = RESTFramework.config.label_fields
|
219
205
|
|
220
206
|
# Preferrably find a database column to use as label.
|
221
207
|
if match = label_fields.find { |f| f.in?(model.column_names) }
|
222
|
-
return sub_fields + [match]
|
208
|
+
return sub_fields + [ match ]
|
223
209
|
end
|
224
210
|
|
225
211
|
# Otherwise, find a method.
|
226
212
|
if match = label_fields.find { |f| model.method_defined?(f) }
|
227
|
-
return sub_fields + [match]
|
213
|
+
return sub_fields + [ match ]
|
228
214
|
end
|
229
215
|
|
230
216
|
return sub_fields
|
231
217
|
end
|
232
218
|
|
233
|
-
|
219
|
+
[ "id", "name" ]
|
234
220
|
end
|
235
221
|
|
236
222
|
# Get a field's id/ids variation.
|
@@ -243,7 +229,7 @@ module RESTFramework::Utils
|
|
243
229
|
return reflection.foreign_key
|
244
230
|
end
|
245
231
|
|
246
|
-
|
232
|
+
nil
|
247
233
|
end
|
248
234
|
|
249
235
|
# Wrap a serializer with an adapter if it is an ActiveModel::Serializer.
|
@@ -252,6 +238,6 @@ module RESTFramework::Utils
|
|
252
238
|
return RESTFramework::ActiveModelSerializerAdapterFactory.for(s)
|
253
239
|
end
|
254
240
|
|
255
|
-
|
241
|
+
s
|
256
242
|
end
|
257
243
|
end
|
data/lib/rest_framework.rb
CHANGED
@@ -9,17 +9,21 @@ module RESTFramework
|
|
9
9
|
BUILTIN_MEMBER_ACTIONS = {
|
10
10
|
show: :get,
|
11
11
|
edit: :get,
|
12
|
-
update: [:put, :patch].freeze,
|
12
|
+
update: [ :put, :patch ].freeze,
|
13
13
|
destroy: :delete,
|
14
14
|
}.freeze
|
15
15
|
RRF_BUILTIN_ACTIONS = {
|
16
16
|
options: :options,
|
17
17
|
}.freeze
|
18
18
|
RRF_BUILTIN_BULK_ACTIONS = {
|
19
|
-
update_all: [:put, :patch].freeze,
|
19
|
+
update_all: [ :put, :patch ].freeze,
|
20
20
|
destroy_all: :delete,
|
21
21
|
}.freeze
|
22
22
|
|
23
|
+
# Storage for extra routes and associated metadata.
|
24
|
+
EXTRA_ACTION_ROUTES = Set.new
|
25
|
+
ROUTE_METADATA = {}
|
26
|
+
|
23
27
|
# We put most vendored external assets into these files to make precompilation and serving faster.
|
24
28
|
EXTERNAL_CSS_NAME = "rest_framework/external.min.css"
|
25
29
|
EXTERNAL_JS_NAME = "rest_framework/external.min.js"
|
@@ -61,12 +65,12 @@ module RESTFramework
|
|
61
65
|
"highlight-a11y-dark.min.css" => {
|
62
66
|
url: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/styles/a11y-dark.min.css",
|
63
67
|
sri: "sha512-Vj6gPCk8EZlqnoveEyuGyYaWZ1+jyjMPg8g4shwyyNlRQl6d3L9At02ZHQr5K6s5duZl/+YKMnM3/8pDhoUphg==",
|
64
|
-
extra_tag_attrs: {class: "rrf-dark-mode"},
|
68
|
+
extra_tag_attrs: { class: "rrf-dark-mode" },
|
65
69
|
},
|
66
70
|
"highlight-a11y-light.min.css" => {
|
67
71
|
url: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/styles/a11y-light.min.css",
|
68
72
|
sri: "sha512-WDk6RzwygsN9KecRHAfm9HTN87LQjqdygDmkHSJxVkVI7ErCZ8ZWxP6T8RvBujY1n2/E4Ac+bn2ChXnp5rnnHA==",
|
69
|
-
extra_tag_attrs: {class: "rrf-light-mode"},
|
73
|
+
extra_tag_attrs: { class: "rrf-light-mode" },
|
70
74
|
},
|
71
75
|
|
72
76
|
# NeatJSON
|
@@ -113,7 +117,7 @@ module RESTFramework
|
|
113
117
|
raise "Unknown asset extension: #{ext}."
|
114
118
|
end
|
115
119
|
|
116
|
-
[name, cfg]
|
120
|
+
[ name, cfg ]
|
117
121
|
}.to_h.freeze
|
118
122
|
# rubocop:enable Layout/LineLength
|
119
123
|
|
@@ -122,8 +126,8 @@ module RESTFramework
|
|
122
126
|
# Global configuration should be kept minimal, as controller-level configurations allows multiple
|
123
127
|
# APIs to be defined to behave differently.
|
124
128
|
class Config
|
125
|
-
DEFAULT_LABEL_FIELDS = %w
|
126
|
-
DEFAULT_SEARCH_COLUMNS = DEFAULT_LABEL_FIELDS + %w
|
129
|
+
DEFAULT_LABEL_FIELDS = %w[name label login title email username url].freeze
|
130
|
+
DEFAULT_SEARCH_COLUMNS = DEFAULT_LABEL_FIELDS + %w[description note].freeze
|
127
131
|
DEFAULT_EXCLUDE_BODY_FIELDS = %w[
|
128
132
|
created_at
|
129
133
|
created_by
|
@@ -136,15 +140,18 @@ module RESTFramework
|
|
136
140
|
authenticity_token
|
137
141
|
].freeze
|
138
142
|
|
139
|
-
#
|
140
|
-
|
141
|
-
|
142
|
-
#
|
143
|
-
#
|
143
|
+
# Permits use of `render(api: obj)` syntax over `render_api(obj)`; `true` by default.
|
144
|
+
attr_accessor :register_api_renderer
|
145
|
+
|
146
|
+
# Run `rrf_finalize` on controllers automatically using a `TracePoint` hook. This is `true` by
|
147
|
+
# default, and can be disabled for performance, and must be global because we have to determine
|
148
|
+
# this before any controller-specific configuration is set. If this is set to `false`, then you
|
149
|
+
# must manually call `rrf_finalize` after any configuration on each controller that needs to
|
150
|
+
# participate in:
|
144
151
|
# - Model delegation, for the helper methods to be defined dynamically.
|
145
152
|
# - Websockets, for `::Channel` class to be defined dynamically.
|
146
153
|
# - Controller configuration freezing.
|
147
|
-
attr_accessor :
|
154
|
+
attr_accessor :auto_finalize
|
148
155
|
|
149
156
|
# Freeze configuration attributes during finalization to prevent accidental mutation.
|
150
157
|
attr_accessor :freeze_config
|
@@ -173,7 +180,11 @@ module RESTFramework
|
|
173
180
|
attr_accessor :use_vendored_assets
|
174
181
|
|
175
182
|
def initialize
|
183
|
+
self.register_api_renderer = true
|
184
|
+
self.auto_finalize = true
|
185
|
+
|
176
186
|
self.show_backtrace = Rails.env.development?
|
187
|
+
|
177
188
|
self.label_fields = DEFAULT_LABEL_FIELDS
|
178
189
|
self.search_columns = DEFAULT_SEARCH_COLUMNS
|
179
190
|
self.exclude_body_fields = DEFAULT_EXCLUDE_BODY_FIELDS
|
@@ -181,7 +192,7 @@ module RESTFramework
|
|
181
192
|
end
|
182
193
|
|
183
194
|
def self.config
|
184
|
-
|
195
|
+
@config ||= Config.new
|
185
196
|
end
|
186
197
|
|
187
198
|
def self.configure
|
@@ -189,7 +200,7 @@ module RESTFramework
|
|
189
200
|
end
|
190
201
|
|
191
202
|
def self.features
|
192
|
-
|
203
|
+
@features ||= {}
|
193
204
|
end
|
194
205
|
end
|
195
206
|
|
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: 1.0.0
|
4
|
+
version: 1.0.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:
|
11
|
+
date: 2025-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -96,12 +96,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
96
96
|
requirements:
|
97
97
|
- - ">="
|
98
98
|
- !ruby/object:Gem::Version
|
99
|
-
version: 2.
|
99
|
+
version: 2.7.5
|
100
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- - "
|
102
|
+
- - ">="
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version:
|
104
|
+
version: '0'
|
105
105
|
requirements: []
|
106
106
|
rubygems_version: 3.4.10
|
107
107
|
signing_key:
|