rest_framework 0.10.0 → 0.11.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 +3 -3
- data/VERSION +1 -1
- data/app/views/rest_framework/routes_and_forms/_html_form.html.erb +6 -6
- data/app/views/rest_framework/routes_and_forms/_raw_form.html.erb +1 -1
- data/app/views/rest_framework/routes_and_forms/routes/_route.html.erb +1 -1
- data/lib/rest_framework/errors/{nil_passed_to_api_response_error.rb → nil_passed_to_render_api_error.rb} +3 -3
- data/lib/rest_framework/errors.rb +1 -1
- data/lib/rest_framework/filters/ordering_filter.rb +4 -7
- data/lib/rest_framework/filters/query_filter.rb +1 -4
- data/lib/rest_framework/filters/ransack_filter.rb +4 -4
- data/lib/rest_framework/filters/search_filter.rb +3 -6
- data/lib/rest_framework/mixins/base_controller_mixin.rb +92 -100
- data/lib/rest_framework/mixins/bulk_model_controller_mixin.rb +7 -7
- data/lib/rest_framework/mixins/model_controller_mixin.rb +215 -190
- data/lib/rest_framework/paginators/page_number_paginator.rb +12 -11
- data/lib/rest_framework/routers.rb +11 -1
- data/lib/rest_framework/serializers/native_serializer.rb +10 -10
- data/lib/rest_framework/utils.rb +24 -24
- metadata +3 -3
@@ -13,34 +13,35 @@ class RESTFramework::Paginators::PageNumberPaginator < RESTFramework::Paginators
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def _page_size
|
16
|
-
page_size =
|
16
|
+
page_size = 1
|
17
17
|
|
18
18
|
# Get from context, if allowed.
|
19
|
-
if @controller.page_size_query_param
|
20
|
-
if page_size = @controller.params[
|
19
|
+
if param = @controller.class.page_size_query_param
|
20
|
+
if page_size = @controller.params[param].presence
|
21
21
|
page_size = page_size.to_i
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
# Otherwise, get from config.
|
26
|
-
if !page_size && @controller.page_size
|
27
|
-
page_size = @controller.page_size
|
26
|
+
if !page_size && @controller.class.page_size
|
27
|
+
page_size = @controller.class.page_size.to_i
|
28
28
|
end
|
29
29
|
|
30
30
|
# Ensure we don't exceed the max page size.
|
31
|
-
|
32
|
-
|
31
|
+
max_page_size = @controller.class.max_page_size&.to_i
|
32
|
+
if max_page_size && page_size > max_page_size
|
33
|
+
page_size = max_page_size
|
33
34
|
end
|
34
35
|
|
35
36
|
# Ensure we return at least 1.
|
36
|
-
return page_size
|
37
|
+
return [page_size, 1].max
|
37
38
|
end
|
38
39
|
|
39
40
|
# Get the page and return it so the caller can serialize it.
|
40
41
|
def get_page(page_number=nil)
|
41
42
|
# If page number isn't provided, infer from the params or use 1 as a fallback value.
|
42
43
|
unless page_number
|
43
|
-
page_number = @controller&.params&.[](@controller.page_query_param&.to_sym)
|
44
|
+
page_number = @controller&.params&.[](@controller.class.page_query_param&.to_sym)
|
44
45
|
if page_number.blank?
|
45
46
|
page_number = 1
|
46
47
|
else
|
@@ -57,9 +58,9 @@ class RESTFramework::Paginators::PageNumberPaginator < RESTFramework::Paginators
|
|
57
58
|
return @data.limit(@page_size).offset(page_index * @page_size)
|
58
59
|
end
|
59
60
|
|
60
|
-
# Wrap the serialized page with appropriate metadata.
|
61
|
+
# Wrap the serialized page with appropriate metadata.
|
61
62
|
def get_paginated_response(serialized_page)
|
62
|
-
page_query_param = @controller.page_query_param
|
63
|
+
page_query_param = @controller.class.page_query_param
|
63
64
|
base_params = @controller.params.to_unsafe_h
|
64
65
|
next_url = if @page_number < @total_pages
|
65
66
|
@controller.url_for({**base_params, page_query_param => @page_number + 1})
|
@@ -27,7 +27,17 @@ module ActionDispatch::Routing
|
|
27
27
|
controller = mod.const_get(name)
|
28
28
|
rescue NameError
|
29
29
|
if fallback_reverse_pluralization
|
30
|
-
|
30
|
+
reraise = false
|
31
|
+
|
32
|
+
begin
|
33
|
+
controller = mod.const_get(name_reverse)
|
34
|
+
rescue
|
35
|
+
reraise = true
|
36
|
+
end
|
37
|
+
|
38
|
+
if reraise
|
39
|
+
raise
|
40
|
+
end
|
31
41
|
else
|
32
42
|
raise
|
33
43
|
end
|
@@ -55,12 +55,12 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
55
55
|
return nil unless @controller
|
56
56
|
|
57
57
|
if @many == true
|
58
|
-
controller_serializer = @controller.
|
58
|
+
controller_serializer = @controller.class.native_serializer_plural_config
|
59
59
|
elsif @many == false
|
60
|
-
controller_serializer = @controller.
|
60
|
+
controller_serializer = @controller.class.native_serializer_singular_config
|
61
61
|
end
|
62
62
|
|
63
|
-
return controller_serializer || @controller.
|
63
|
+
return 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
|
@@ -114,8 +114,8 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
114
114
|
def filter_from_request(cfg)
|
115
115
|
return cfg unless @controller
|
116
116
|
|
117
|
-
except_param = @controller.
|
118
|
-
only_param = @controller.
|
117
|
+
except_param = @controller.class.native_serializer_except_query_param
|
118
|
+
only_param = @controller.class.native_serializer_only_query_param
|
119
119
|
if except_param && except = @controller.request&.query_parameters&.[](except_param).presence
|
120
120
|
if except = except.split(",").map(&:strip).map(&:to_sym).presence
|
121
121
|
# Filter `only`, `except` (additive), `include`, `methods`, and `serializer_methods`.
|
@@ -160,10 +160,10 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
160
160
|
def _get_associations_limit
|
161
161
|
return @_get_associations_limit if defined?(@_get_associations_limit)
|
162
162
|
|
163
|
-
limit = @controller&.native_serializer_associations_limit
|
163
|
+
limit = @controller&.class&.native_serializer_associations_limit
|
164
164
|
|
165
165
|
# Extract the limit from the query parameters if it's set.
|
166
|
-
if query_param = @controller&.native_serializer_associations_limit_query_param
|
166
|
+
if query_param = @controller&.class&.native_serializer_associations_limit_query_param
|
167
167
|
if @controller.request.query_parameters.key?(query_param)
|
168
168
|
query_limit = @controller.request.query_parameters[query_param].to_i
|
169
169
|
if query_limit > 0
|
@@ -195,7 +195,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
195
195
|
attachment_reflections = @model.attachment_reflections
|
196
196
|
|
197
197
|
fields.each do |f|
|
198
|
-
field_config = @controller.class.
|
198
|
+
field_config = @controller.class.field_configuration[f]
|
199
199
|
next if field_config[:write_only]
|
200
200
|
|
201
201
|
if f.in?(column_names)
|
@@ -226,7 +226,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
226
226
|
#
|
227
227
|
# # Even though we use a serializer method, if the count will later be added, then put
|
228
228
|
# # this field into the includes_map.
|
229
|
-
# if @controller.native_serializer_include_associations_count
|
229
|
+
# if @controller.class.native_serializer_include_associations_count
|
230
230
|
# includes_map[f] = f.to_sym
|
231
231
|
# end
|
232
232
|
else
|
@@ -235,7 +235,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
235
235
|
end
|
236
236
|
|
237
237
|
# If we need to include the association count, then add it here.
|
238
|
-
if @controller.native_serializer_include_associations_count
|
238
|
+
if @controller.class.native_serializer_include_associations_count
|
239
239
|
method_name = "#{f}.count"
|
240
240
|
serializer_methods[method_name] = method_name
|
241
241
|
self.define_singleton_method(method_name) do |record|
|
data/lib/rest_framework/utils.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
module RESTFramework::Utils
|
2
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
|
-
# additional metadata fields.
|
4
|
+
# Convert `extra_actions` hash to a consistent format: `{path:, methods:, kwargs:}`.
|
6
5
|
#
|
7
6
|
# If a controller is provided, labels will be added to any metadata fields.
|
8
7
|
def self.parse_extra_actions(extra_actions, controller: nil)
|
9
8
|
return (extra_actions || {}).map { |k, v|
|
10
9
|
path = k
|
11
|
-
metadata = {}
|
12
10
|
|
13
11
|
# Convert structure to path/methods/kwargs.
|
14
12
|
if v.is_a?(Hash) # Allow kwargs to be used to define path differently from the key.
|
@@ -19,11 +17,9 @@ module RESTFramework::Utils
|
|
19
17
|
methods = v.delete(:method)
|
20
18
|
end
|
21
19
|
|
22
|
-
#
|
23
|
-
metadata = v
|
24
|
-
|
25
|
-
# Add label to fields.
|
26
|
-
if controller && metadata[:fields]
|
20
|
+
# Add label to metadata fields, if any exist.
|
21
|
+
metadata = v[:metadata]
|
22
|
+
if controller && metadata&.key?(:fields)
|
27
23
|
metadata[:fields] = metadata[:fields].map { |f|
|
28
24
|
[f, {}]
|
29
25
|
}.to_h if metadata[:fields].is_a?(Array)
|
@@ -56,8 +52,6 @@ module RESTFramework::Utils
|
|
56
52
|
path: path,
|
57
53
|
methods: methods,
|
58
54
|
kwargs: kwargs,
|
59
|
-
type: :extra,
|
60
|
-
metadata: metadata.presence,
|
61
55
|
}.compact,
|
62
56
|
]
|
63
57
|
}.to_h
|
@@ -91,25 +85,28 @@ module RESTFramework::Utils
|
|
91
85
|
current_levels = current_path.count("/")
|
92
86
|
current_comparable_path = %r{^#{Regexp.quote(self.comparable_path(current_path))}(/|$)}
|
93
87
|
|
94
|
-
#
|
95
|
-
|
96
|
-
route_props = {
|
97
|
-
with_path_args: ->(r) {
|
98
|
-
r.format(r.required_parts.each_with_index.map { |p, i| [p, path_args[i]] }.to_h)
|
99
|
-
},
|
100
|
-
}
|
88
|
+
# Get current route path parameters.
|
89
|
+
path_params = current_route.required_parts.map { |n| request.path_parameters[n] }
|
101
90
|
|
102
91
|
# Return routes that match our current route subdomain/pattern, grouped by controller. We
|
103
92
|
# precompute certain properties of the route for performance.
|
104
|
-
return
|
93
|
+
return application_routes.routes.select { |r|
|
105
94
|
# We `select` first to avoid unnecessarily calculating metadata for routes we don't even want
|
106
95
|
# to show.
|
107
96
|
(r.defaults[:subdomain].blank? || r.defaults[:subdomain] == request.subdomain) &&
|
108
|
-
|
109
|
-
|
110
|
-
|
97
|
+
current_comparable_path.match?(self.comparable_path(r.path.spec.to_s)) &&
|
98
|
+
r.defaults[:controller].present? &&
|
99
|
+
r.defaults[:action].present?
|
111
100
|
}.map { |r|
|
112
101
|
path = r.path.spec.to_s.gsub("(.:format)", "")
|
102
|
+
|
103
|
+
# Starts at the number of levels in current path, and removes the `(.:format)` at the end.
|
104
|
+
relative_path = path.split("/")[current_levels..]&.join("/").presence || "/"
|
105
|
+
|
106
|
+
# This path is what would need to be concatenated onto the current path to get to the
|
107
|
+
# destination path.
|
108
|
+
concat_path = relative_path.gsub(/^[^\/]*/, "").presence || "/"
|
109
|
+
|
113
110
|
levels = path.count("/")
|
114
111
|
matches_path = current_path == path
|
115
112
|
matches_params = r.required_parts.length == current_route.required_parts.length
|
@@ -118,8 +115,11 @@ module RESTFramework::Utils
|
|
118
115
|
route: r,
|
119
116
|
verb: r.verb,
|
120
117
|
path: path,
|
121
|
-
|
122
|
-
|
118
|
+
path_with_params: r.format(
|
119
|
+
r.required_parts.each_with_index.map { |p, i| [p, path_params[i]] }.to_h,
|
120
|
+
),
|
121
|
+
relative_path: relative_path,
|
122
|
+
concat_path: concat_path,
|
123
123
|
controller: r.defaults[:controller].presence,
|
124
124
|
action: r.defaults[:action].presence,
|
125
125
|
matches_path: matches_path,
|
@@ -234,7 +234,7 @@ module RESTFramework::Utils
|
|
234
234
|
end
|
235
235
|
|
236
236
|
# Get a field's id/ids variation.
|
237
|
-
def self.
|
237
|
+
def self.id_field_for(field, reflection)
|
238
238
|
if reflection.collection?
|
239
239
|
return "#{field.singularize}_ids"
|
240
240
|
elsif reflection.belongs_to?
|
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.11.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: 2024-12-
|
11
|
+
date: 2024-12-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -54,7 +54,7 @@ files:
|
|
54
54
|
- lib/rest_framework/engine.rb
|
55
55
|
- lib/rest_framework/errors.rb
|
56
56
|
- lib/rest_framework/errors/base_error.rb
|
57
|
-
- lib/rest_framework/errors/
|
57
|
+
- lib/rest_framework/errors/nil_passed_to_render_api_error.rb
|
58
58
|
- lib/rest_framework/errors/unknown_model_error.rb
|
59
59
|
- lib/rest_framework/filters.rb
|
60
60
|
- lib/rest_framework/filters/base_filter.rb
|