rest_framework 0.9.14 → 0.9.16

Sign up to get free protection for your applications and to get access to all the features.
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