rest_framework 0.9.14 → 0.9.16

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f0a39ff15a5a6714fb7dc52f11e7db3cebe918805a44b0a8486567debebcefac
4
- data.tar.gz: 5e2e530f249b567c64bb0d527875b291180052b07d61919bbbf76ae3f5ad7b1b
3
+ metadata.gz: 59084182eeedcec7d3f1a1a913a99e55a6139bb394e4c712744c5d80778db800
4
+ data.tar.gz: 552ea8a39833dc6a3ec4c689f120ba549af0db49a3fafa29d63cd4cb17d85a85
5
5
  SHA512:
6
- metadata.gz: c15b1d0904dc34e2cbc095628b5d642213c0d33b6387e52b38660cf78b6552bc32818dca5ecbc5de710502139c7308fffb67a0a2aa3049749833c5e64a6757b5
7
- data.tar.gz: 5656754554aa3bb4acc7ee333b72f21ea848d3e3cc8c06acf9e16d3529b427acfec9e00b3bac3ae67536b39608640146bcaab1459db77a7c6c46e6545e72dbae
6
+ metadata.gz: cffd1cde2cbf956d46344018c137b723397118f3aa4ea16c2d9abf5c9d9694c8a78d8f706f96e28c637ec4f58d692553da372a832a0bd44cc58154134b733d33
7
+ data.tar.gz: 1eea97e45fc0f4c47edbdb04a8de05fe6e383e259ea1d3ff48196b6601aeb87341aa6750f8eb4411dd0e16934452c5a02b2d26877a9ec8382ae538312f305603
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.14
1
+ 0.9.16
@@ -3,11 +3,10 @@
3
3
  <head>
4
4
  <title><%= @title %></title>
5
5
 
6
- <%# These dynamic tags cannot be cached, so include directly instead of in `head` partial. %>
7
6
  <%= csrf_meta_tags %>
8
7
  <%= csp_meta_tag rescue nil %>
9
8
 
10
- <%= render partial: "rest_framework/head", cached: true %>
9
+ <%= render partial: "rest_framework/head" %>
11
10
 
12
11
  <%= yield :head %>
13
12
  </head>
@@ -296,8 +296,9 @@
296
296
  document.write(content)
297
297
  document.close()
298
298
 
299
- // Trigger `DOMContentLoaded` manually so our custom JavaScript works.
300
- document.dispatchEvent(new Event("DOMContentLoaded", {bubbles: true, cancelable: true}))
299
+ // It seems that `DOMContentLoaded` is already triggered on `document.close()`.
300
+ // // Trigger `DOMContentLoaded` manually so our custom JavaScript works.
301
+ // // document.dispatchEvent(new Event("DOMContentLoaded", {bubbles: true, cancelable: true}))
301
302
  }
302
303
 
303
304
  // Refresh the window as a `GET` request.
@@ -3,7 +3,7 @@
3
3
  <%= render partial: "rest_framework/heading/actions" if @route_groups.present? %>
4
4
  <h1 style="margin: 0"><%= @heading_title || @title %></h1>
5
5
  <% if @description.present? %>
6
- <br><br><p style="display: inline-block; margin-bottom: 0"><%= @description %></p>
6
+ <p style="display: inline-block; margin-bottom: 0; margin-top: 1em"><%= @description %></p>
7
7
  <% end %>
8
8
  </div>
9
9
  </div>
@@ -26,14 +26,14 @@
26
26
  %>
27
27
  <div class="mb-2">
28
28
  <% if metadata[:kind] == "rich_text" %>
29
- <label class="form-label w-100"><%= controller.class.get_label(f) %></label>
29
+ <label class="form-label w-100"><%= controller.class.label_for(f) %></label>
30
30
  <%= form.rich_text_area f %>
31
31
  <% elsif metadata[:kind] == "attachment" %>
32
- <label class="form-label w-100"><%= controller.class.get_label(f) %>
32
+ <label class="form-label w-100"><%= controller.class.label_for(f) %>
33
33
  <%= form.file_field f, multiple: metadata.dig(:attachment, :macro) == :has_many_attached %>
34
34
  </label>
35
35
  <% else %>
36
- <label class="form-label w-100"><%= controller.class.get_label(f) %>
36
+ <label class="form-label w-100"><%= controller.class.label_for(f) %>
37
37
  <%= form.text_field f, class: "form-control form-control-sm" %>
38
38
  </label>
39
39
  <% end %>
@@ -40,7 +40,7 @@
40
40
  local: true,
41
41
  }.compact) do |form| %>
42
42
  <% attachment_reflections.each do |field, ref| %>
43
- <label class="form-label w-100"><%= controller.class.get_label(field) %>
43
+ <label class="form-label w-100"><%= controller.class.label_for(field) %>
44
44
  <%= form.file_field field, multiple: ref.macro == :has_many_attached %>
45
45
  </label>
46
46
  <% end %>
@@ -3,7 +3,7 @@ class RESTFramework::Filters::BaseFilter
3
3
  @controller = controller
4
4
  end
5
5
 
6
- def get_filtered_data(data)
6
+ def filter_data(data)
7
7
  raise NotImplementedError
8
8
  end
9
9
  end
@@ -1,5 +1,5 @@
1
1
  # A filter backend which handles ordering of the recordset.
2
- class RESTFramework::Filters::ModelOrderingFilter < RESTFramework::Filters::BaseFilter
2
+ class RESTFramework::Filters::OrderingFilter < RESTFramework::Filters::BaseFilter
3
3
  # Get a list of ordering fields for the current action.
4
4
  def _get_fields
5
5
  return @controller.ordering_fields&.map(&:to_s) || @controller.get_fields
@@ -38,7 +38,7 @@ class RESTFramework::Filters::ModelOrderingFilter < RESTFramework::Filters::Base
38
38
  end
39
39
 
40
40
  # Order data according to the request query parameters.
41
- def get_filtered_data(data)
41
+ def filter_data(data)
42
42
  ordering = self._get_ordering
43
43
  reorder = !@controller.ordering_no_reorder
44
44
 
@@ -51,4 +51,7 @@ class RESTFramework::Filters::ModelOrderingFilter < RESTFramework::Filters::Base
51
51
  end
52
52
 
53
53
  # Alias for convenience.
54
- RESTFramework::ModelOrderingFilter = RESTFramework::Filters::ModelOrderingFilter
54
+ RESTFramework::OrderingFilter = RESTFramework::Filters::OrderingFilter
55
+
56
+ # TODO: Compatibility; remove in 1.0.
57
+ RESTFramework::ModelOrderingFilter = RESTFramework::Filters::OrderingFilter
@@ -1,14 +1,14 @@
1
1
  # A simple filtering backend that supports filtering a recordset based on query parameters.
2
- class RESTFramework::Filters::ModelQueryFilter < RESTFramework::Filters::BaseFilter
2
+ class RESTFramework::Filters::QueryFilter < RESTFramework::Filters::BaseFilter
3
3
  NIL_VALUES = ["nil", "null"].freeze
4
4
 
5
- # Get a list of filterset fields for the current action.
5
+ # Get a list of filter fields for the current action.
6
6
  def _get_fields
7
7
  # Always return a list of strings; `@controller.get_fields` already does this.
8
- return @controller.class.filterset_fields&.map(&:to_s) || @controller.get_fields
8
+ return @controller.class.filter_fields&.map(&:to_s) || @controller.get_fields
9
9
  end
10
10
 
11
- # Filter params for keys allowed by the current action's filterset_fields/fields config.
11
+ # Filter params for keys allowed by the current action's filter_fields/fields config.
12
12
  def _get_filter_params
13
13
  fields = self._get_fields
14
14
  includes = []
@@ -22,7 +22,7 @@ class RESTFramework::Filters::ModelQueryFilter < RESTFramework::Filters::BaseFil
22
22
  field, sub_field = match[1..2]
23
23
  next false unless field.in?(fields)
24
24
 
25
- sub_fields = @controller.class.get_field_config(field)[:sub_fields] || []
25
+ sub_fields = @controller.class.field_config_for(field)[:sub_fields] || []
26
26
  if sub_field.in?(sub_fields)
27
27
  includes << field.to_sym
28
28
  next true
@@ -49,7 +49,7 @@ class RESTFramework::Filters::ModelQueryFilter < RESTFramework::Filters::BaseFil
49
49
  end
50
50
 
51
51
  # Filter data according to the request query parameters.
52
- def get_filtered_data(data)
52
+ def filter_data(data)
53
53
  filter_params, includes = self._get_filter_params
54
54
 
55
55
  if filter_params.any?
@@ -65,4 +65,7 @@ class RESTFramework::Filters::ModelQueryFilter < RESTFramework::Filters::BaseFil
65
65
  end
66
66
 
67
67
  # Alias for convenience.
68
- RESTFramework::ModelQueryFilter = RESTFramework::Filters::ModelQueryFilter
68
+ RESTFramework::QueryFilter = RESTFramework::Filters::QueryFilter
69
+
70
+ # TODO: Compatibility; remove in 1.0.
71
+ RESTFramework::ModelQueryFilter = RESTFramework::Filters::QueryFilter
@@ -1,7 +1,7 @@
1
1
  # Adapter for the `ransack` gem.
2
2
  class RESTFramework::Filters::RansackFilter < RESTFramework::Filters::BaseFilter
3
3
  # Filter data according to the request query parameters.
4
- def get_filtered_data(data)
4
+ def filter_data(data)
5
5
  q = @controller.request.query_parameters[@controller.ransack_query_param]
6
6
 
7
7
  if q.present?
@@ -1,5 +1,4 @@
1
- # Multi-field text searching on models.
2
- class RESTFramework::Filters::ModelSearchFilter < RESTFramework::Filters::BaseFilter
1
+ class RESTFramework::Filters::SearchFilter < RESTFramework::Filters::BaseFilter
3
2
  # Get a list of search fields for the current action.
4
3
  def _get_fields
5
4
  if search_fields = @controller.search_fields
@@ -13,7 +12,7 @@ class RESTFramework::Filters::ModelSearchFilter < RESTFramework::Filters::BaseFi
13
12
  end
14
13
 
15
14
  # Filter data according to the request query parameters.
16
- def get_filtered_data(data)
15
+ def filter_data(data)
17
16
  search = @controller.request.query_parameters[@controller.search_query_param]
18
17
 
19
18
  if search.present?
@@ -41,4 +40,7 @@ class RESTFramework::Filters::ModelSearchFilter < RESTFramework::Filters::BaseFi
41
40
  end
42
41
 
43
42
  # Alias for convenience.
44
- RESTFramework::ModelSearchFilter = RESTFramework::Filters::ModelSearchFilter
43
+ RESTFramework::SearchFilter = RESTFramework::Filters::SearchFilter
44
+
45
+ # TODO: Compatibility; remove in 1.0.
46
+ RESTFramework::ModelSearchFilter = RESTFramework::Filters::SearchFilter
@@ -3,7 +3,7 @@ end
3
3
 
4
4
  require_relative "filters/base_filter"
5
5
 
6
- require_relative "filters/model_ordering_filter"
7
- require_relative "filters/model_query_filter"
8
- require_relative "filters/model_search_filter"
6
+ require_relative "filters/ordering_filter"
7
+ require_relative "filters/query_filter"
9
8
  require_relative "filters/ransack_filter"
9
+ require_relative "filters/search_filter"
@@ -1,6 +1,6 @@
1
1
  # This module provides the common functionality for any controller mixins, a `root` action, and
2
- # the ability to route arbitrary actions with `extra_actions`. This is also where `api_response`
3
- # is defined.
2
+ # the ability to route arbitrary actions with `extra_actions`. This is also where `render_api` is
3
+ # implemented.
4
4
  module RESTFramework::Mixins::BaseControllerMixin
5
5
  RRF_BASE_CONFIG = {
6
6
  extra_actions: nil,
@@ -11,16 +11,14 @@ module RESTFramework::Mixins::BaseControllerMixin
11
11
  title: nil,
12
12
  description: nil,
13
13
  inflect_acronyms: ["ID", "IDs", "REST", "API", "APIs"].freeze,
14
- }
15
- RRF_BASE_INSTANCE_CONFIG = {
16
- filter_backends: nil,
17
14
 
18
15
  # Options related to serialization.
19
16
  rescue_unknown_format_with: :json,
20
17
  serializer_class: nil,
21
18
  serialize_to_json: true,
22
19
  serialize_to_xml: true,
23
-
20
+ }
21
+ RRF_BASE_INSTANCE_CONFIG = {
24
22
  # Options related to pagination.
25
23
  paginator_class: nil,
26
24
  page_size: 20,
@@ -35,12 +33,12 @@ module RESTFramework::Mixins::BaseControllerMixin
35
33
 
36
34
  # Default action for API root.
37
35
  def root
38
- api_response({message: "This is the API root."})
36
+ render_api({message: "This is the API root."})
39
37
  end
40
38
 
41
39
  module ClassMethods
42
- # Get the title of this controller. By default, this is the name of the controller class,
43
- # titleized and with any custom inflection acronyms applied.
40
+ # By default, this is the name of the controller class, titleized and with any custom inflection
41
+ # acronyms applied.
44
42
  def get_title
45
43
  return self.title || RESTFramework::Utils.inflect(
46
44
  self.name.demodulize.chomp("Controller").titleize(keep_id_suffix: true),
@@ -49,7 +47,7 @@ module RESTFramework::Mixins::BaseControllerMixin
49
47
  end
50
48
 
51
49
  # Get a label from a field/column name, titleized and inflected.
52
- def get_label(s)
50
+ def label_for(s)
53
51
  return RESTFramework::Utils.inflect(
54
52
  s.to_s.titleize(keep_id_suffix: true),
55
53
  self.inflect_acronyms,
@@ -57,7 +55,7 @@ module RESTFramework::Mixins::BaseControllerMixin
57
55
  end
58
56
 
59
57
  # Collect actions (including extra actions) metadata for this controller.
60
- def get_actions_metadata
58
+ def actions_metadata
61
59
  actions = {}
62
60
 
63
61
  # Start with builtin actions.
@@ -67,7 +65,7 @@ module RESTFramework::Mixins::BaseControllerMixin
67
65
  next unless self.method_defined?(action)
68
66
 
69
67
  actions[action] = {
70
- path: "", methods: methods, type: :builtin, metadata: {label: self.get_label(action)}
68
+ path: "", methods: methods, type: :builtin, metadata: {label: self.label_for(action)}
71
69
  }
72
70
  end
73
71
 
@@ -76,7 +74,7 @@ module RESTFramework::Mixins::BaseControllerMixin
76
74
  next unless self.method_defined?(action)
77
75
 
78
76
  actions[action] = {
79
- path: "", methods: methods, type: :builtin, metadata: {label: self.get_label(action)}
77
+ path: "", methods: methods, type: :builtin, metadata: {label: self.label_for(action)}
80
78
  }
81
79
  end
82
80
 
@@ -89,7 +87,7 @@ module RESTFramework::Mixins::BaseControllerMixin
89
87
  end
90
88
 
91
89
  # Collect member actions (including extra member actions) metadata for this controller.
92
- def get_member_actions_metadata
90
+ def member_actions_metadata
93
91
  actions = {}
94
92
 
95
93
  # Start with builtin actions.
@@ -97,7 +95,7 @@ module RESTFramework::Mixins::BaseControllerMixin
97
95
  next unless self.method_defined?(action)
98
96
 
99
97
  actions[action] = {
100
- path: "", methods: methods, type: :builtin, metadata: {label: self.get_label(action)}
98
+ path: "", methods: methods, type: :builtin, metadata: {label: self.label_for(action)}
101
99
  }
102
100
  end
103
101
 
@@ -109,8 +107,7 @@ module RESTFramework::Mixins::BaseControllerMixin
109
107
  return actions
110
108
  end
111
109
 
112
- # Get a hash of metadata to be rendered in the `OPTIONS` response. Cache the result.
113
- def get_options_metadata
110
+ def options_metadata
114
111
  return {
115
112
  title: self.get_title,
116
113
  description: self.description,
@@ -119,8 +116,8 @@ module RESTFramework::Mixins::BaseControllerMixin
119
116
  self.serialize_to_json ? "application/json" : nil,
120
117
  self.serialize_to_xml ? "application/xml" : nil,
121
118
  ].compact,
122
- actions: self.get_actions_metadata,
123
- member_actions: self.get_member_actions_metadata,
119
+ actions: self.actions_metadata,
120
+ member_actions: self.member_actions_metadata,
124
121
  }.compact
125
122
  end
126
123
 
@@ -203,47 +200,24 @@ module RESTFramework::Mixins::BaseControllerMixin
203
200
  end
204
201
  end
205
202
 
206
- # Get the configured serializer class.
207
- def get_serializer_class
208
- return nil unless serializer_class = self.serializer_class
209
-
210
- # Support dynamically resolving serializer given a symbol or string.
211
- serializer_class = serializer_class.to_s if serializer_class.is_a?(Symbol)
212
- if serializer_class.is_a?(String)
213
- serializer_class = self.class.const_get(serializer_class)
214
- end
215
-
216
- # Wrap it with an adapter if it's an active_model_serializer.
217
- if defined?(ActiveModel::Serializer) && (serializer_class < ActiveModel::Serializer)
218
- serializer_class = RESTFramework::ActiveModelSerializerAdapterFactory.for(serializer_class)
203
+ def serializer_class
204
+ # TODO: Compatibility; remove in 1.0.
205
+ if klass = self.try(:get_serializer_class)
206
+ return klass
219
207
  end
220
208
 
221
- return serializer_class
209
+ return self.class.serializer_class
222
210
  end
223
211
 
224
212
  # Serialize the given data using the `serializer_class`.
225
213
  def serialize(data, **kwargs)
226
- return self.get_serializer_class.new(data, controller: self, **kwargs).serialize
214
+ return RESTFramework::Utils.wrap_ams(self.serializer_class).new(
215
+ data, controller: self, **kwargs
216
+ ).serialize
227
217
  end
228
218
 
229
- # Get filtering backends, defaulting to no backends.
230
- def get_filter_backends
231
- return self.filter_backends || []
232
- end
233
-
234
- # Filter an arbitrary data set over all configured filter backends.
235
- def get_filtered_data(data)
236
- # Apply each filter sequentially.
237
- self.get_filter_backends.each do |filter_class|
238
- filter = filter_class.new(controller: self)
239
- data = filter.get_filtered_data(data)
240
- end
241
-
242
- return data
243
- end
244
-
245
- def get_options_metadata
246
- return self.class.get_options_metadata
219
+ def options_metadata
220
+ return self.class.options_metadata
247
221
  end
248
222
 
249
223
  def rrf_error_handler(e)
@@ -295,25 +269,25 @@ module RESTFramework::Mixins::BaseControllerMixin
295
269
  begin
296
270
  respond_to do |format|
297
271
  if payload == ""
298
- format.json { head(kwargs[:status] || :no_content) } if self.serialize_to_json
299
- format.xml { head(kwargs[:status] || :no_content) } if self.serialize_to_xml
272
+ format.json { head(kwargs[:status] || :no_content) } if self.class.serialize_to_json
273
+ format.xml { head(kwargs[:status] || :no_content) } if self.class.serialize_to_xml
300
274
  else
301
275
  format.json {
302
276
  render(json: payload, **kwargs.merge(json_kwargs))
303
- } if self.serialize_to_json
277
+ } if self.class.serialize_to_json
304
278
  format.xml {
305
279
  render(xml: payload, **kwargs.merge(xml_kwargs))
306
- } if self.serialize_to_xml
280
+ } if self.class.serialize_to_xml
307
281
  # TODO: possibly support more formats here if supported?
308
282
  end
309
283
  format.html {
310
284
  @payload = payload
311
285
  if payload == ""
312
- @json_payload = "" if self.serialize_to_json
313
- @xml_payload = "" if self.serialize_to_xml
286
+ @json_payload = "" if self.class.serialize_to_json
287
+ @xml_payload = "" if self.class.serialize_to_xml
314
288
  else
315
- @json_payload = payload.to_json if self.serialize_to_json
316
- @xml_payload = payload.to_xml if self.serialize_to_xml
289
+ @json_payload = payload.to_json if self.class.serialize_to_json
290
+ @xml_payload = payload.to_xml if self.class.serialize_to_xml
317
291
  end
318
292
  @title ||= self.class.get_title
319
293
  @description ||= self.class.description
@@ -329,7 +303,7 @@ module RESTFramework::Mixins::BaseControllerMixin
329
303
  }
330
304
  end
331
305
  rescue ActionController::UnknownFormat
332
- if !already_rescued_unknown_format && rescue_format = self.rescue_unknown_format_with
306
+ if !already_rescued_unknown_format && rescue_format = self.class.rescue_unknown_format_with
333
307
  request.format = rescue_format
334
308
  already_rescued_unknown_format = true
335
309
  retry
@@ -339,9 +313,11 @@ module RESTFramework::Mixins::BaseControllerMixin
339
313
  end
340
314
  end
341
315
 
342
- # Provide a generic `OPTIONS` response with metadata such as available actions.
316
+ # TODO: Might make this the default render method in the future.
317
+ alias_method :render_api, :api_response
318
+
343
319
  def options
344
- return api_response(self.get_options_metadata)
320
+ return api_response(self.options_metadata)
345
321
  end
346
322
  end
347
323
 
@@ -6,7 +6,7 @@ module RESTFramework::Mixins::BulkCreateModelMixin
6
6
  # While bulk update/destroy are obvious because they create new router endpoints, bulk create
7
7
  # overloads the existing collection `POST` endpoint, so we add a special key to the options
8
8
  # metadata to indicate bulk create is supported.
9
- def get_options_metadata
9
+ def options_metadata
10
10
  return super.merge({bulk_create: true})
11
11
  end
12
12