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.
@@ -13,34 +13,35 @@ class RESTFramework::Paginators::PageNumberPaginator < RESTFramework::Paginators
13
13
  end
14
14
 
15
15
  def _page_size
16
- page_size = nil
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[@controller.page_size_query_param].presence
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
- if @controller.max_page_size && page_size > @controller.max_page_size
32
- page_size = @controller.max_page_size
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.zero? ? 1 : 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. TODO: include links.
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
- controller = mod.const_get(name_reverse)
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.try(:native_serializer_plural_config)
58
+ controller_serializer = @controller.class.native_serializer_plural_config
59
59
  elsif @many == false
60
- controller_serializer = @controller.try(:native_serializer_singular_config)
60
+ controller_serializer = @controller.class.native_serializer_singular_config
61
61
  end
62
62
 
63
- return controller_serializer || @controller.try(:native_serializer_config)
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.try(:native_serializer_except_query_param)
118
- only_param = @controller.try(:native_serializer_only_query_param)
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.field_config_for(f)
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|
@@ -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:}`, and
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
- # First, remove the route metadata.
23
- metadata = v.delete(:metadata) || {}
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
- # Add helpful properties of the current route.
95
- path_args = current_route.required_parts.map { |n| request.path_parameters[n] }
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 route_props, application_routes.routes.select { |r|
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
- current_comparable_path.match?(self.comparable_path(r.path.spec.to_s)) &&
109
- r.defaults[:controller].present? &&
110
- r.defaults[:action].present?
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
- # Starts at the number of levels in current path, and removes the `(.:format)` at the end.
122
- relative_path: path.split("/")[current_levels..]&.join("/").presence || "/",
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.get_id_field(field, reflection)
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.10.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-23 00:00:00.000000000 Z
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/nil_passed_to_api_response_error.rb
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