rest_framework 0.9.11 → 0.9.15
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 +1 -1
- data/VERSION +1 -1
- data/app/views/rest_framework/routes_and_forms/_html_form.html.erb +3 -2
- data/app/views/rest_framework/routes_and_forms/_raw_form.html.erb +3 -2
- data/lib/rest_framework/filters/model_ordering_filter.rb +2 -1
- data/lib/rest_framework/mixins/model_controller_mixin.rb +25 -11
- data/lib/rest_framework/serializers/native_serializer.rb +11 -0
- data/lib/rest_framework/utils.rb +12 -11
- data/lib/rest_framework.rb +1 -1
- 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: 734af1c9a436fd842c36503794ef16b94e4b0d3f7ad91d011bcd12d06e4b1e21
|
4
|
+
data.tar.gz: d4c0140985a5405750cdd092c4a70b092be69b3523a3c088d2268711c38e5ad1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4fc442c77a0c8543913ceacd7a7116f9e044ee1d9b0e3e08a5c58ddb6d00ee12b7f719c83e7aed233070075bb031aa8a90cabc7337bd57e28883aca4221d5ea6
|
7
|
+
data.tar.gz: 2f60ffddea13e956a3a0a0ec909d2de533cc0c5b350af75467f7e006b5133c982192cbcc28da7cb566803458c76917ae702f4838c3f0096722a94f5309babb7a
|
data/README.md
CHANGED
@@ -149,4 +149,4 @@ end
|
|
149
149
|
After you clone the repository, cd'ing into the directory should create a new gemset if you are using RVM.
|
150
150
|
Then run `bin/setup` to install the appropriate gems and set things up.
|
151
151
|
|
152
|
-
The top-level `bin/rails` proxies all Rails commands to the test project, so you can operate it via the usual commands (e.g., `rails test`, `rails server` and `rails console`).
|
152
|
+
The top-level `bin/rails` proxies all Rails commands to the test project, so you can operate it via the usual commands (e.g., `rails test`, `rails server` and `rails console`). For development, use `foreman start` to run the web server and the job queue.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.15
|
@@ -10,13 +10,14 @@
|
|
10
10
|
</label>
|
11
11
|
</div>
|
12
12
|
|
13
|
-
<%= form_with(
|
13
|
+
<%= form_with(**{
|
14
14
|
model: @record,
|
15
15
|
url: "",
|
16
16
|
method: :patch,
|
17
17
|
id: "htmlForm",
|
18
18
|
scope: "",
|
19
|
-
|
19
|
+
local: true,
|
20
|
+
}.compact) do |form| %>
|
20
21
|
<% controller.get_fields.map(&:to_s).each do |f| %>
|
21
22
|
<%
|
22
23
|
# Don't provide form fields for associations or primary keys.
|
@@ -32,12 +32,13 @@
|
|
32
32
|
<% if @is_model_controller && model = controller.class.get_model %>
|
33
33
|
<% if attachment_reflections = model.attachment_reflections.presence %>
|
34
34
|
<div class="mb-2" style="display: none" id="rawFilesFormWrapper">
|
35
|
-
<%= form_with(
|
35
|
+
<%= form_with(**{
|
36
36
|
model: @record,
|
37
37
|
url: "",
|
38
38
|
id: "rawFilesForm",
|
39
39
|
scope: "",
|
40
|
-
|
40
|
+
local: true,
|
41
|
+
}.compact) do |form| %>
|
41
42
|
<% attachment_reflections.each do |field, ref| %>
|
42
43
|
<label class="form-label w-100"><%= controller.class.get_label(field) %>
|
43
44
|
<%= form.file_field field, multiple: ref.macro == :has_many_attached %>
|
@@ -16,7 +16,8 @@ class RESTFramework::Filters::ModelOrderingFilter < RESTFramework::Filters::Base
|
|
16
16
|
if order_string.present?
|
17
17
|
ordering = {}.with_indifferent_access
|
18
18
|
|
19
|
-
order_string.
|
19
|
+
order_string = order_string.join(",") if order_string.is_a?(Array)
|
20
|
+
order_string.split(",").map(&:strip).each do |field|
|
20
21
|
if field[0] == "-"
|
21
22
|
column = field[1..-1]
|
22
23
|
direction = :desc
|
@@ -6,9 +6,11 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
6
6
|
return {
|
7
7
|
io: StringIO.new(Base64.decode64(payload)),
|
8
8
|
content_type: content_type,
|
9
|
-
filename: "
|
9
|
+
filename: "file_#{field}#{Rack::Mime::MIME_TYPES.invert[content_type]}",
|
10
10
|
}
|
11
11
|
}
|
12
|
+
ACTIVESTORAGE_KEYS = [:io, :content_type, :filename, :identify, :key]
|
13
|
+
|
12
14
|
include RESTFramework::BaseControllerMixin
|
13
15
|
|
14
16
|
RRF_BASE_MODEL_CONFIG = {
|
@@ -22,8 +24,6 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
22
24
|
|
23
25
|
# Options for what should be included/excluded from default fields.
|
24
26
|
exclude_associations: false,
|
25
|
-
include_active_storage: false,
|
26
|
-
include_action_text: false,
|
27
27
|
}
|
28
28
|
RRF_BASE_MODEL_INSTANCE_CONFIG = {
|
29
29
|
# Attributes for finding records.
|
@@ -413,18 +413,21 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
413
413
|
# For fields, automatically add `_id`/`_ids` and `_attributes` variations for associations.
|
414
414
|
variations = []
|
415
415
|
hash_variations = {}
|
416
|
+
alt_hash_variations = {}
|
416
417
|
reflections = self.class.get_model.reflections
|
417
418
|
@_get_allowed_parameters = self.get_fields.map { |f|
|
418
419
|
f = f.to_s
|
419
420
|
|
420
421
|
# ActiveStorage Integration: `has_one_attached`.
|
421
422
|
if reflections.key?("#{f}_attachment")
|
423
|
+
hash_variations[f] = ACTIVESTORAGE_KEYS
|
422
424
|
next f
|
423
425
|
end
|
424
426
|
|
425
427
|
# ActiveStorage Integration: `has_many_attached`.
|
426
428
|
if reflections.key?("#{f}_attachments")
|
427
429
|
hash_variations[f] = []
|
430
|
+
alt_hash_variations[f] = ACTIVESTORAGE_KEYS
|
428
431
|
next nil
|
429
432
|
end
|
430
433
|
|
@@ -445,7 +448,9 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
445
448
|
end
|
446
449
|
|
447
450
|
if self.permit_nested_attributes_assignment
|
448
|
-
hash_variations["#{f}_attributes"] =
|
451
|
+
hash_variations["#{f}_attributes"] = (
|
452
|
+
self.class.get_field_config(f)[:sub_fields] + ["_destroy"]
|
453
|
+
)
|
449
454
|
end
|
450
455
|
|
451
456
|
# Associations are not allowed to be submitted in their bare form.
|
@@ -453,6 +458,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
453
458
|
}.compact
|
454
459
|
@_get_allowed_parameters += variations
|
455
460
|
@_get_allowed_parameters << hash_variations
|
461
|
+
@_get_allowed_parameters << alt_hash_variations
|
456
462
|
return @_get_allowed_parameters
|
457
463
|
end
|
458
464
|
|
@@ -522,14 +528,22 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
522
528
|
#
|
523
529
|
# rubocop:enable Layout/LineLength
|
524
530
|
self.class.get_model.attachment_reflections.keys.each do |k|
|
525
|
-
next unless (body_params[k].is_a?(String) && body_params[k].match?(BASE64_REGEX)) ||
|
526
|
-
(body_params[k].is_a?(Array) && body_params[k].all? { |v|
|
527
|
-
v.is_a?(String) && v.match?(BASE64_REGEX)
|
528
|
-
})
|
529
|
-
|
530
531
|
if body_params[k].is_a?(Array)
|
531
|
-
body_params[k] = body_params[k].map { |v|
|
532
|
-
|
532
|
+
body_params[k] = body_params[k].map { |v|
|
533
|
+
if v.is_a?(String)
|
534
|
+
BASE64_TRANSLATE.call(k, v)
|
535
|
+
elsif v.is_a?(ActionController::Parameters)
|
536
|
+
if v[:io].is_a?(String)
|
537
|
+
v[:io] = StringIO.new(Base64.decode64(v[:io]))
|
538
|
+
end
|
539
|
+
v
|
540
|
+
end
|
541
|
+
}
|
542
|
+
elsif body_params[k].is_a?(ActionController::Parameters)
|
543
|
+
if body_params[k][:io].is_a?(String)
|
544
|
+
body_params[k][:io] = StringIO.new(Base64.decode64(body_params[k][:io]))
|
545
|
+
end
|
546
|
+
elsif body_params[k].is_a?(String)
|
533
547
|
body_params[k] = BASE64_TRANSLATE.call(k, body_params[k])
|
534
548
|
end
|
535
549
|
end
|
@@ -221,6 +221,14 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
221
221
|
self.define_singleton_method(f) do |record|
|
222
222
|
next record.send(f).limit(limit).as_json(**sub_config)
|
223
223
|
end
|
224
|
+
|
225
|
+
# Disable this for now, as it's not clear if this improves performance of count.
|
226
|
+
#
|
227
|
+
# # Even though we use a serializer method, if the count will later be added, then put
|
228
|
+
# # this field into the includes_map.
|
229
|
+
# if @controller.native_serializer_include_associations_count
|
230
|
+
# includes_map[f] = f.to_sym
|
231
|
+
# end
|
224
232
|
else
|
225
233
|
includes[f] = sub_config
|
226
234
|
includes_map[f] = f.to_sym
|
@@ -263,6 +271,9 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
263
271
|
end
|
264
272
|
elsif @model.method_defined?(f)
|
265
273
|
methods << f
|
274
|
+
else
|
275
|
+
# Assume anything else is a virtual column.
|
276
|
+
columns << f
|
266
277
|
end
|
267
278
|
end
|
268
279
|
|
data/lib/rest_framework/utils.rb
CHANGED
@@ -15,13 +15,18 @@ module RESTFramework::Utils
|
|
15
15
|
# Symbolize keys (which also makes a copy so we don't mutate the original).
|
16
16
|
v = v.symbolize_keys
|
17
17
|
methods = v.delete(:methods)
|
18
|
+
if v.key?(:method)
|
19
|
+
methods = v.delete(:method)
|
20
|
+
end
|
18
21
|
|
19
22
|
# First, remove the route metadata.
|
20
23
|
metadata = v.delete(:metadata) || {}
|
21
24
|
|
22
25
|
# Add label to fields.
|
23
26
|
if controller && metadata[:fields]
|
24
|
-
metadata[:fields] = metadata[:fields].map { |f|
|
27
|
+
metadata[:fields] = metadata[:fields].map { |f|
|
28
|
+
[f, {}]
|
29
|
+
}.to_h if metadata[:fields].is_a?(Array)
|
25
30
|
metadata[:fields]&.each do |field, cfg|
|
26
31
|
cfg[:label] = controller.get_label(field) unless cfg[:label]
|
27
32
|
end
|
@@ -99,12 +104,10 @@ module RESTFramework::Utils
|
|
99
104
|
return route_props, application_routes.routes.select { |r|
|
100
105
|
# We `select` first to avoid unnecessarily calculating metadata for routes we don't even want
|
101
106
|
# to show.
|
102
|
-
(
|
103
|
-
(r.defaults[:subdomain].blank? || r.defaults[:subdomain] == request.subdomain) &&
|
107
|
+
(r.defaults[:subdomain].blank? || r.defaults[:subdomain] == request.subdomain) &&
|
104
108
|
current_comparable_path.match?(self.comparable_path(r.path.spec.to_s)) &&
|
105
109
|
r.defaults[:controller].present? &&
|
106
110
|
r.defaults[:action].present?
|
107
|
-
)
|
108
111
|
}.map { |r|
|
109
112
|
path = r.path.spec.to_s.gsub("(.:format)", "")
|
110
113
|
levels = path.count("/")
|
@@ -156,9 +159,10 @@ module RESTFramework::Utils
|
|
156
159
|
)
|
157
160
|
parsed_fields += fields_hash[:include].map(&:to_s) if fields_hash[:include]
|
158
161
|
parsed_fields -= fields_hash[:exclude].map(&:to_s) if fields_hash[:exclude]
|
162
|
+
parsed_fields -= fields_hash[:except].map(&:to_s) if fields_hash[:except]
|
159
163
|
|
160
164
|
# Warn for any unknown keys.
|
161
|
-
(fields_hash.keys - [:only, :include, :exclude]).each do |k|
|
165
|
+
(fields_hash.keys - [:only, :except, :include, :exclude]).each do |k|
|
162
166
|
Rails.logger.warn("RRF: Unknown key in fields hash: #{k}")
|
163
167
|
end
|
164
168
|
|
@@ -171,15 +175,12 @@ module RESTFramework::Utils
|
|
171
175
|
# strings, not symbols.
|
172
176
|
def self.fields_for(model, exclude_associations: nil)
|
173
177
|
foreign_keys = model.reflect_on_all_associations(:belongs_to).map(&:foreign_key)
|
178
|
+
base_fields = model.column_names.reject { |c| c.in?(foreign_keys) }
|
174
179
|
|
175
|
-
if exclude_associations
|
176
|
-
return model.column_names.reject { |c| c.in?(foreign_keys) }
|
177
|
-
end
|
180
|
+
return base_fields if exclude_associations
|
178
181
|
|
179
182
|
# Add associations in addition to normal columns.
|
180
|
-
return model.
|
181
|
-
c.in?(foreign_keys)
|
182
|
-
} + model.reflections.map { |association, ref|
|
183
|
+
return base_fields + model.reflections.map { |association, ref|
|
183
184
|
# Ignore associations for which we have custom integrations.
|
184
185
|
if ref.class_name.in?(%w(ActiveStorage::Attachment ActiveStorage::Blob ActionText::RichText))
|
185
186
|
next nil
|
data/lib/rest_framework.rb
CHANGED
@@ -149,7 +149,7 @@ module RESTFramework
|
|
149
149
|
# Freeze configuration attributes during finalization to prevent accidental mutation.
|
150
150
|
attr_accessor :freeze_config
|
151
151
|
|
152
|
-
# Specify reverse association tables that are typically very large,
|
152
|
+
# Specify reverse association tables that are typically very large, and therefore should not be
|
153
153
|
# added to fields by default.
|
154
154
|
attr_accessor :large_reverse_association_tables
|
155
155
|
|
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.9.
|
4
|
+
version: 0.9.15
|
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: 2024-12-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|