rest_framework 1.0.0.rc1 → 1.0.1

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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -2
  3. data/VERSION +1 -1
  4. data/app/views/rest_framework/_head.html.erb +3 -1
  5. data/app/views/rest_framework/_heading.html.erb +1 -0
  6. data/app/views/rest_framework/head/_extra.html.erb +0 -0
  7. data/app/views/rest_framework/heading/_actions.html.erb +2 -1
  8. data/app/views/rest_framework/heading/_extra.html.erb +0 -0
  9. data/app/views/rest_framework/heading/actions/_extra.html.erb +0 -0
  10. data/app/views/rest_framework/routes_and_forms/_html_form.html.erb +2 -2
  11. data/lib/rest_framework/errors/nil_passed_to_render_api_error.rb +1 -1
  12. data/lib/rest_framework/errors/unknown_model_error.rb +1 -1
  13. data/lib/rest_framework/filters/ordering_filter.rb +3 -3
  14. data/lib/rest_framework/filters/query_filter.rb +14 -14
  15. data/lib/rest_framework/filters/ransack_filter.rb +1 -1
  16. data/lib/rest_framework/filters/search_filter.rb +3 -3
  17. data/lib/rest_framework/generators/controller_generator.rb +2 -2
  18. data/lib/rest_framework/mixins/base_controller_mixin.rb +34 -33
  19. data/lib/rest_framework/mixins/bulk_model_controller_mixin.rb +8 -15
  20. data/lib/rest_framework/mixins/model_controller_mixin.rb +91 -65
  21. data/lib/rest_framework/paginators/page_number_paginator.rb +6 -6
  22. data/lib/rest_framework/routers.rb +10 -16
  23. data/lib/rest_framework/serializers/active_model_serializer_adapter_factory.rb +4 -2
  24. data/lib/rest_framework/serializers/base_serializer.rb +7 -5
  25. data/lib/rest_framework/serializers/native_serializer.rb +82 -129
  26. data/lib/rest_framework/utils.rb +27 -26
  27. data/lib/rest_framework/version.rb +1 -1
  28. data/lib/rest_framework.rb +24 -17
  29. data/vendor/assets/javascripts/rest_framework/external.min.js +4 -4
  30. data/vendor/assets/stylesheets/rest_framework/external.min.css +3 -3
  31. metadata +8 -5
@@ -5,13 +5,13 @@ module RESTFramework::Mixins::BaseModelControllerMixin
5
5
  return value unless BASE64_REGEX.match?(value)
6
6
 
7
7
  _, content_type, payload = value.match(BASE64_REGEX).to_a
8
- return {
8
+ {
9
9
  io: StringIO.new(Base64.decode64(payload)),
10
10
  content_type: content_type,
11
11
  filename: "file_#{field}#{Rack::Mime::MIME_TYPES.invert[content_type]}",
12
12
  }
13
13
  }
14
- ACTIVESTORAGE_KEYS = [:io, :content_type, :filename, :identify, :key]
14
+ ACTIVESTORAGE_KEYS = [ :io, :content_type, :filename, :identify, :key ]
15
15
 
16
16
  include RESTFramework::BaseControllerMixin
17
17
 
@@ -23,27 +23,30 @@ module RESTFramework::Mixins::BaseModelControllerMixin
23
23
  # Attributes for configuring record fields.
24
24
  fields: nil,
25
25
  field_config: nil,
26
+ read_only_fields: RESTFramework.config.read_only_fields,
27
+ write_only_fields: RESTFramework.config.write_only_fields,
28
+ hidden_fields: nil,
26
29
 
27
30
  # Attributes for finding records.
28
31
  find_by_fields: nil,
29
- find_by_query_param: "find_by",
32
+ find_by_query_param: "find_by".freeze,
30
33
 
31
34
  # Options for what should be included/excluded from default fields.
32
35
  exclude_associations: false,
33
36
 
34
37
  # Options for handling request body parameters.
35
38
  allowed_parameters: nil,
36
- filter_pk_from_request_body: true,
37
- exclude_body_fields: RESTFramework.config.exclude_body_fields,
38
39
 
39
40
  # Attributes for the default native serializer.
40
41
  native_serializer_config: nil,
41
42
  native_serializer_singular_config: nil,
42
43
  native_serializer_plural_config: nil,
43
- native_serializer_only_query_param: "only",
44
- native_serializer_except_query_param: "except",
44
+ native_serializer_only_query_param: "only".freeze,
45
+ native_serializer_except_query_param: "except".freeze,
46
+ native_serializer_include_query_param: "include".freeze,
47
+ native_serializer_exclude_query_param: "exclude".freeze,
45
48
  native_serializer_associations_limit: nil,
46
- native_serializer_associations_limit_query_param: "associations_limit",
49
+ native_serializer_associations_limit_query_param: "associations_limit".freeze,
47
50
  native_serializer_include_associations_count: false,
48
51
 
49
52
  # Attributes for filtering, ordering, and searching.
@@ -51,19 +54,19 @@ module RESTFramework::Mixins::BaseModelControllerMixin
51
54
  RESTFramework::QueryFilter,
52
55
  RESTFramework::OrderingFilter,
53
56
  RESTFramework::SearchFilter,
54
- ],
57
+ ].freeze,
55
58
  filter_recordset_before_find: true,
56
59
  filter_fields: nil,
57
60
  ordering_fields: nil,
58
- ordering_query_param: "ordering",
61
+ ordering_query_param: "ordering".freeze,
59
62
  ordering_no_reorder: false,
60
63
  search_fields: nil,
61
- search_query_param: "search",
64
+ search_query_param: "search".freeze,
62
65
  search_ilike: false,
63
66
  ransack_options: nil,
64
- ransack_query_param: "q",
67
+ ransack_query_param: "q".freeze,
65
68
  ransack_distinct: true,
66
- ransack_distinct_query_param: "distinct",
69
+ ransack_distinct_query_param: "distinct".freeze,
67
70
 
68
71
  # Options for association assignment.
69
72
  permit_id_assignment: true,
@@ -74,7 +77,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
74
77
  }
75
78
 
76
79
  module ClassMethods
77
- IGNORE_VALIDATORS_WITH_KEYS = [:if, :unless].freeze
80
+ IGNORE_VALIDATORS_WITH_KEYS = [ :if, :unless ].freeze
78
81
 
79
82
  def get_model
80
83
  return @model if @model
@@ -91,7 +94,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
91
94
 
92
95
  # Override to include ActiveRecord i18n-translated column names.
93
96
  def label_for(s)
94
- return self.get_model.human_attribute_name(s, default: super)
97
+ self.get_model.human_attribute_name(s, default: super)
95
98
  end
96
99
 
97
100
  # Get the available fields. Fallback to this controller's model columns, or an empty array. This
@@ -121,7 +124,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
121
124
  input_fields = input_fields.map(&:to_s)
122
125
  end
123
126
 
124
- return input_fields
127
+ input_fields
125
128
  end
126
129
 
127
130
  # Get a full field configuration, including defaults and inferred values.
@@ -135,13 +138,15 @@ module RESTFramework::Mixins::BaseModelControllerMixin
135
138
  reflections = model.reflections
136
139
  attributes = model._default_attributes
137
140
  readonly_attributes = model.readonly_attributes
138
- exclude_body_fields = self.exclude_body_fields&.map(&:to_s)
141
+ read_only_fields = self.read_only_fields&.map(&:to_s)&.to_set || Set[]
142
+ write_only_fields = self.write_only_fields&.map(&:to_s)&.to_set || Set[]
143
+ hidden_fields = self.hidden_fields&.map(&:to_s)&.to_set || Set[]
139
144
  rich_text_association_names = model.reflect_on_all_associations(:has_one)
140
145
  .collect(&:name)
141
146
  .select { |n| n.to_s.start_with?("rich_text_") }
142
147
  attachment_reflections = model.attachment_reflections
143
148
 
144
- return @field_configuration = self.get_fields.map { |f|
149
+ @field_configuration = self.get_fields.map { |f|
145
150
  cfg = field_config[f]&.dup || {}
146
151
  cfg[:label] ||= self.label_for(f)
147
152
 
@@ -149,14 +154,29 @@ module RESTFramework::Mixins::BaseModelControllerMixin
149
154
  if model.primary_key == f
150
155
  cfg[:primary_key] = true
151
156
 
152
- unless cfg.key?(:readonly)
153
- cfg[:readonly] = true
157
+ unless cfg.key?(:read_only)
158
+ cfg[:read_only] = true
154
159
  end
155
160
  end
156
161
 
157
- # Annotate readonly attributes.
158
- if f.in?(readonly_attributes) || f.in?(exclude_body_fields)
159
- cfg[:readonly] = true
162
+ # Annotate field mutability and display properties.
163
+ cfg[:read_only] = true if f.in?(readonly_attributes) || f.in?(read_only_fields)
164
+ cfg[:write_only] = true if f.in?(write_only_fields)
165
+ cfg[:hidden] = true if f.in?(hidden_fields)
166
+
167
+ # Raise warnings on some bad combinations of properties.
168
+ if cfg[:write_only]
169
+ if cfg[:read_only]
170
+ Rails.logger.warn("RRF: `#{f}` write_only conflicts with read_only.")
171
+ end
172
+
173
+ if cfg[:hidden]
174
+ Rails.logger.warn("RRF: `#{f}` write_only implies hidden.")
175
+ end
176
+
177
+ if cfg[:hidden_from_index]
178
+ Rails.logger.warn("RRF: `#{f}` write_only implies hidden_from_index.")
179
+ end
160
180
  end
161
181
 
162
182
  # Annotate column data.
@@ -167,12 +187,12 @@ module RESTFramework::Mixins::BaseModelControllerMixin
167
187
  end
168
188
 
169
189
  # Add default values from the model's schema.
170
- if column_default = column_defaults[f] && !cfg[:default].nil?
171
- cfg[:default] ||= column_default
190
+ if cfg[:default].nil? && (column_default = column_defaults[f])
191
+ cfg[:default] = column_default
172
192
  end
173
193
 
174
194
  # Add metadata from the model's attributes hash.
175
- if attribute = attributes[f]
195
+ if attributes.key?(f) && attribute = attributes[f]
176
196
  if cfg[:default].nil? && default = attribute.value_before_type_cast
177
197
  cfg[:default] = default
178
198
  end
@@ -218,7 +238,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
218
238
  v[:kind] = "method"
219
239
  end
220
240
 
221
- next [sf, v]
241
+ next [ sf, v ]
222
242
  }.to_h.compact.presence
223
243
 
224
244
  # Determine if we render id/ids fields. Unfortunately, `has_one` does not provide this
@@ -231,7 +251,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
231
251
  if self.permit_nested_attributes_assignment && (
232
252
  nested_opts = model.nested_attributes_options[f.to_sym].presence
233
253
  )
234
- cfg[:nested_attributes_options] = {field: "#{f}_attributes", **nested_opts}
254
+ cfg[:nested_attributes_options] = { field: "#{f}_attributes", **nested_opts }
235
255
  end
236
256
 
237
257
  begin
@@ -256,6 +276,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
256
276
  # Determine if this is just a method.
257
277
  if !cfg[:kind] && model.method_defined?(f)
258
278
  cfg[:kind] = "method"
279
+ cfg[:read_only] = true if cfg[:read_only].nil?
259
280
  end
260
281
 
261
282
  # Collect validator options into a hash on their type, while also updating `required` based
@@ -283,8 +304,8 @@ module RESTFramework::Mixins::BaseModelControllerMixin
283
304
  cfg[:validators][kind] << options
284
305
  end
285
306
 
286
- next [f, cfg]
287
- }.to_h.with_indifferent_access
307
+ next [ f, cfg ]
308
+ }.to_h.compact.with_indifferent_access
288
309
  end
289
310
 
290
311
  def openapi_schema
@@ -295,7 +316,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
295
316
  required: field_configuration.select { |_, cfg| cfg[:required] }.keys,
296
317
  type: "object",
297
318
  properties: field_configuration.map { |f, cfg|
298
- v = {title: cfg[:label]}
319
+ v = { title: cfg[:label] }
299
320
 
300
321
  if cfg[:kind] == "association"
301
322
  v[:type] = cfg[:reflection].collection? ? "array" : "object"
@@ -309,7 +330,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
309
330
  v[:type] = cfg[:type]
310
331
  end
311
332
 
312
- v[:readOnly] = true if cfg[:readonly]
333
+ v[:readOnly] = true if cfg[:read_only]
313
334
  v[:default] = cfg[:default] if cfg.key?(:default)
314
335
 
315
336
  if enum_variants = cfg[:enum_variants]
@@ -324,7 +345,14 @@ module RESTFramework::Mixins::BaseModelControllerMixin
324
345
  v[:"x-rrf-kind"] = cfg[:kind] if cfg[:kind]
325
346
 
326
347
  if cfg[:reflection]
327
- v[:"x-rrf-reflection"] = cfg[:reflection]
348
+ v[:"x-rrf-reflection"] = {
349
+ class_name: cfg[:reflection].class_name,
350
+ foreign_key: cfg[:reflection].foreign_key,
351
+ association_foreign_key: cfg[:reflection].association_foreign_key,
352
+ association_primary_key: cfg[:reflection].association_primary_key,
353
+ inverse_of: cfg[:reflection].inverse_of&.name,
354
+ join_table: cfg[:reflection].join_table,
355
+ }.compact
328
356
  v[:"x-rrf-association_pk"] = cfg[:association_pk]
329
357
  v[:"x-rrf-sub_fields"] = cfg[:sub_fields]
330
358
  v[:"x-rrf-sub_fields_metadata"] = cfg[:sub_fields_metadata]
@@ -332,15 +360,15 @@ module RESTFramework::Mixins::BaseModelControllerMixin
332
360
  v[:"x-rrf-nested_attributes_options"] = cfg[:nested_attributes_options]
333
361
  end
334
362
 
335
- next [f, v]
363
+ next [ f, v ]
336
364
  }.to_h,
337
365
  }
338
366
 
339
- return @openapi_schema
367
+ @openapi_schema
340
368
  end
341
369
 
342
370
  def openapi_schema_name
343
- return @openapi_schema_name ||= self.name.chomp("Controller").gsub("::", ".")
371
+ @openapi_schema_name ||= self.name.chomp("Controller").gsub("::", ".")
344
372
  end
345
373
 
346
374
  def openapi_paths(_routes, tag)
@@ -358,7 +386,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
358
386
  if !extra_action && method != "options" # rubocop:disable Style/Next
359
387
  # Add schema to request body content types.
360
388
  action.dig(:requestBody, :content)&.each do |_t, v|
361
- v[:schema] = {"$ref" => "#/components/schemas/#{schema_name}"}
389
+ v[:schema] = { "$ref" => "#/components/schemas/#{schema_name}" }
362
390
  end
363
391
 
364
392
  # Add schema to successful response body content types.
@@ -368,7 +396,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
368
396
  response[:content]&.each do |t, v|
369
397
  next if t == "text/html"
370
398
 
371
- v[:schema] = {"$ref" => "#/components/schemas/#{schema_name}"}
399
+ v[:schema] = { "$ref" => "#/components/schemas/#{schema_name}" }
372
400
  end
373
401
  end
374
402
 
@@ -385,7 +413,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
385
413
  end
386
414
  end
387
415
 
388
- return paths
416
+ paths
389
417
  end
390
418
 
391
419
  def openapi_document(request, route_group_name, _routes)
@@ -396,7 +424,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
396
424
  document[:components][:schemas] ||= {}
397
425
  document[:components][:schemas][self.openapi_schema_name] = self.openapi_schema
398
426
 
399
- return document.merge(
427
+ document.merge(
400
428
  {
401
429
  "x-rrf-primary_key" => self.get_model.primary_key,
402
430
  "x-rrf-callbacks" => self._process_action_callbacks.as_json,
@@ -471,7 +499,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
471
499
  end
472
500
 
473
501
  def get_fields
474
- return self.class.get_fields(input_fields: self.class.fields)
502
+ self.class.get_fields(input_fields: self.class.fields)
475
503
  end
476
504
 
477
505
  # Get a hash of strong parameters for the current action.
@@ -490,7 +518,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
490
518
  config = self.class.field_configuration[f]
491
519
 
492
520
  # ActionText Integration:
493
- if self.class.enable_action_text && reflections.key?("rich_test_#{f}")
521
+ if self.class.enable_action_text && reflections.key?("rich_text_#{f}")
494
522
  next f
495
523
  end
496
524
 
@@ -520,7 +548,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
520
548
  # TODO: Consider adjusting this based on `nested_attributes_options`.
521
549
  if self.class.permit_nested_attributes_assignment
522
550
  hash_variations["#{f}_attributes"] = (
523
- config[:sub_fields] + ["_destroy"]
551
+ config[:sub_fields] + [ "_destroy" ]
524
552
  )
525
553
  end
526
554
 
@@ -534,11 +562,11 @@ module RESTFramework::Mixins::BaseModelControllerMixin
534
562
  @_get_allowed_parameters += variations
535
563
  @_get_allowed_parameters << hash_variations
536
564
 
537
- return @_get_allowed_parameters
565
+ @_get_allowed_parameters
538
566
  end
539
567
 
540
568
  def get_serializer_class
541
- return super || RESTFramework::NativeSerializer
569
+ super || RESTFramework::NativeSerializer
542
570
  end
543
571
 
544
572
  # Use strong parameters to filter the request body.
@@ -610,8 +638,8 @@ module RESTFramework::Mixins::BaseModelControllerMixin
610
638
  body_params = if allowed_params == true
611
639
  ActionController::Parameters.new(data).permit!
612
640
  elsif bulk_mode
613
- pk = bulk_mode == :update ? [pk] : []
614
- ActionController::Parameters.new(data).permit({_json: allowed_params + pk})
641
+ pk = bulk_mode == :update ? [ pk ] : []
642
+ ActionController::Parameters.new(data).permit({ _json: allowed_params + pk })
615
643
  else
616
644
  ActionController::Parameters.new(data).permit(*allowed_params)
617
645
  end
@@ -625,15 +653,13 @@ module RESTFramework::Mixins::BaseModelControllerMixin
625
653
  body_params[k].unshift(*v)
626
654
  end
627
655
 
628
- # Filter primary key, if configured.
629
- if self.class.filter_pk_from_request_body && bulk_mode != :update
630
- body_params.delete(pk)
656
+ # Filter read-only fields.
657
+ body_params.delete_if do |f, _|
658
+ cfg = self.class.field_configuration[f]
659
+ cfg && cfg[:read_only]
631
660
  end
632
661
 
633
- # Filter fields in `exclude_body_fields`.
634
- (self.class.exclude_body_fields || []).each { |f| body_params.delete(f) }
635
-
636
- return body_params
662
+ body_params
637
663
  end
638
664
  alias_method :get_create_params, :get_body_params
639
665
  alias_method :get_update_params, :get_body_params
@@ -647,14 +673,14 @@ module RESTFramework::Mixins::BaseModelControllerMixin
647
673
  return model.all
648
674
  end
649
675
 
650
- return nil
676
+ nil
651
677
  end
652
678
 
653
679
  # Filter the recordset and return records this request has access to.
654
680
  def get_records
655
681
  data = self.get_recordset
656
682
 
657
- return @records ||= self.class.filter_backends&.reduce(data) { |d, filter|
683
+ @records ||= self.class.filter_backends&.reduce(data) { |d, filter|
658
684
  filter.new(controller: self).filter_data(d)
659
685
  } || data
660
686
  end
@@ -687,14 +713,14 @@ module RESTFramework::Mixins::BaseModelControllerMixin
687
713
 
688
714
  # Return the record. Route key is always `:id` by Rails' convention.
689
715
  if is_pk
690
- return @record = collection.find(request.path_parameters[:id])
716
+ @record = collection.find(request.path_parameters[:id])
691
717
  else
692
- return @record = collection.find_by!(find_by_key => request.path_parameters[:id])
718
+ @record = collection.find_by!(find_by_key => request.path_parameters[:id])
693
719
  end
694
720
  end
695
721
 
696
722
  # Determine what collection to call `create` on.
697
- def get_create_from
723
+ def create_from
698
724
  if self.class.create_from_recordset
699
725
  # Create with any properties inherited from the recordset. We exclude any `select` clauses
700
726
  # in case model callbacks need to call `count` on this collection, which typically raises a
@@ -713,8 +739,8 @@ module RESTFramework::Mixins::BaseModelControllerMixin
713
739
  # the serializer directly. This would fail for active model serializers, but maybe we don't
714
740
  # care?
715
741
  s = RESTFramework::Utils.wrap_ams(self.get_serializer_class)
716
- return records.map do |record|
717
- s.new(record, controller: self).serialize.merge!({errors: record.errors.presence}.compact)
742
+ records.map do |record|
743
+ s.new(record, controller: self).serialize.merge!({ errors: record.errors.presence }.compact)
718
744
  end
719
745
  end
720
746
  end
@@ -743,7 +769,7 @@ module RESTFramework::Mixins::ListModelMixin
743
769
  end
744
770
  end
745
771
 
746
- return records
772
+ records
747
773
  end
748
774
  end
749
775
 
@@ -762,7 +788,7 @@ module RESTFramework::Mixins::CreateModelMixin
762
788
 
763
789
  # Perform the `create!` call and return the created record.
764
790
  def create!
765
- return self.get_create_from.create!(self.get_create_params)
791
+ self.create_from.create!(self.get_create_params)
766
792
  end
767
793
  end
768
794
 
@@ -776,7 +802,7 @@ module RESTFramework::Mixins::UpdateModelMixin
776
802
  def update!
777
803
  record = self.get_record
778
804
  record.update!(self.get_update_params)
779
- return record
805
+ record
780
806
  end
781
807
  end
782
808
 
@@ -789,7 +815,7 @@ module RESTFramework::Mixins::DestroyModelMixin
789
815
 
790
816
  # Perform the `destroy!` call and return the destroyed (and frozen) record.
791
817
  def destroy!
792
- return self.get_record.destroy!
818
+ self.get_record.destroy!
793
819
  end
794
820
  end
795
821
 
@@ -34,11 +34,11 @@ class RESTFramework::Paginators::PageNumberPaginator < RESTFramework::Paginators
34
34
  end
35
35
 
36
36
  # Ensure we return at least 1.
37
- return [page_size, 1].max
37
+ [ page_size, 1 ].max
38
38
  end
39
39
 
40
40
  # Get the page and return it so the caller can serialize it.
41
- def get_page(page_number=nil)
41
+ def get_page(page_number = nil)
42
42
  # If page number isn't provided, infer from the params or use 1 as a fallback value.
43
43
  unless page_number
44
44
  page_number = @controller&.params&.[](@controller.class.page_query_param&.to_sym)
@@ -55,7 +55,7 @@ class RESTFramework::Paginators::PageNumberPaginator < RESTFramework::Paginators
55
55
 
56
56
  # Get the data page and return it so the caller can serialize the data in the proper format.
57
57
  page_index = @page_number - 1
58
- return @data.limit(@page_size).offset(page_index * @page_size)
58
+ @data.limit(@page_size).offset(page_index * @page_size)
59
59
  end
60
60
 
61
61
  # Wrap the serialized page with appropriate metadata.
@@ -63,13 +63,13 @@ class RESTFramework::Paginators::PageNumberPaginator < RESTFramework::Paginators
63
63
  page_query_param = @controller.class.page_query_param
64
64
  base_params = @controller.params.to_unsafe_h
65
65
  next_url = if @page_number < @total_pages
66
- @controller.url_for({**base_params, page_query_param => @page_number + 1})
66
+ @controller.url_for({ **base_params, page_query_param => @page_number + 1 })
67
67
  end
68
68
  previous_url = if @page_number > 1
69
- @controller.url_for({**base_params, page_query_param => @page_number - 1})
69
+ @controller.url_for({ **base_params, page_query_param => @page_number - 1 })
70
70
  end
71
71
 
72
- return {
72
+ {
73
73
  count: @count,
74
74
  page: @page_number,
75
75
  page_size: @page_size,
@@ -43,10 +43,10 @@ module ActionDispatch::Routing
43
43
  end
44
44
  end
45
45
 
46
- return controller
46
+ controller
47
47
  end
48
48
 
49
- # Interal interface for routing extra actions.
49
+ # Internal interface for routing extra actions.
50
50
  def _route_extra_actions(actions, &block)
51
51
  parsed_actions = RESTFramework::Utils.parse_extra_actions(actions)
52
52
 
@@ -84,13 +84,7 @@ module ActionDispatch::Routing
84
84
  unscoped = kwargs.delete(:unscoped)
85
85
 
86
86
  # Determine plural/singular resource.
87
- force_singular = kwargs.delete(:force_singular)
88
- force_plural = kwargs.delete(:force_plural)
89
- if force_singular
90
- singular = true
91
- elsif force_plural
92
- singular = false
93
- elsif !controller_class.singleton_controller.nil?
87
+ if !controller_class.singleton_controller.nil?
94
88
  singular = controller_class.singleton_controller
95
89
  else
96
90
  singular = default_singular
@@ -98,7 +92,7 @@ module ActionDispatch::Routing
98
92
  resource_method = singular ? :resource : :resources
99
93
 
100
94
  # Call either `resource` or `resources`, passing appropriate modifiers.
101
- skip = RESTFramework::Utils.get_skipped_builtin_actions(controller_class)
95
+ skip = RESTFramework::Utils.get_skipped_builtin_actions(controller_class, singular)
102
96
  public_send(resource_method, name, except: skip, **kwargs) do
103
97
  if controller_class.respond_to?(:extra_member_actions)
104
98
  member do
@@ -114,7 +108,7 @@ module ActionDispatch::Routing
114
108
  RESTFramework::RRF_BUILTIN_ACTIONS.each do |action, methods|
115
109
  next unless controller_class.method_defined?(action)
116
110
 
117
- [methods].flatten.each do |m|
111
+ [ methods ].flatten.each do |m|
118
112
  public_send(m, "", action: action) if self.respond_to?(m)
119
113
  end
120
114
  end
@@ -123,7 +117,7 @@ module ActionDispatch::Routing
123
117
  RESTFramework::RRF_BUILTIN_BULK_ACTIONS.each do |action, methods|
124
118
  next unless controller_class.method_defined?(action)
125
119
 
126
- [methods].flatten.each do |m|
120
+ [ methods ].flatten.each do |m|
127
121
  public_send(m, "", action: action) if self.respond_to?(m)
128
122
  end
129
123
  end
@@ -154,7 +148,7 @@ module ActionDispatch::Routing
154
148
  end
155
149
 
156
150
  # Route a controller without the default resourceful paths.
157
- def rest_route(name=nil, **kwargs, &block)
151
+ def rest_route(name = nil, **kwargs, &block)
158
152
  controller = kwargs.delete(:controller) || name
159
153
  route_root_to = kwargs.delete(:route_root_to)
160
154
  if controller.is_a?(Class)
@@ -184,7 +178,7 @@ module ActionDispatch::Routing
184
178
  RESTFramework::RRF_BUILTIN_ACTIONS.each do |action, methods|
185
179
  next unless controller_class.method_defined?(action)
186
180
 
187
- [methods].flatten.each do |m|
181
+ [ methods ].flatten.each do |m|
188
182
  public_send(m, "", action: action) if self.respond_to?(m)
189
183
  end
190
184
  end
@@ -201,7 +195,7 @@ module ActionDispatch::Routing
201
195
  end
202
196
 
203
197
  # Route a controller's `#root` to '/' in the current scope/namespace, along with other actions.
204
- def rest_root(name=nil, **kwargs, &block)
198
+ def rest_root(name = nil, **kwargs, &block)
205
199
  # By default, use RootController#root.
206
200
  root_action = kwargs.delete(:action) || :root
207
201
  controller = kwargs.delete(:controller) || name || :root
@@ -211,7 +205,7 @@ module ActionDispatch::Routing
211
205
  kwargs[:path] = ""
212
206
  end
213
207
 
214
- return rest_route(controller, route_root_to: root_action, **kwargs) do
208
+ rest_route(controller, route_root_to: root_action, **kwargs) do
215
209
  yield if block_given?
216
210
  end
217
211
  end
@@ -1,18 +1,20 @@
1
1
  # This is a helper factory to wrap an ActiveModelSerializer to provide a `serialize` method which
2
2
  # accepts both collections and individual records. Use `.for` to build adapters.
3
+ # :nocov:
3
4
  class RESTFramework::Serializers::ActiveModelSerializerAdapterFactory
4
5
  def self.for(active_model_serializer)
5
- return Class.new(active_model_serializer) do
6
+ Class.new(active_model_serializer) do
6
7
  def serialize
7
8
  if self.object.respond_to?(:to_ary)
8
9
  return self.object.map { |r| self.class.superclass.new(r).serializable_hash }
9
10
  end
10
11
 
11
- return self.serializable_hash
12
+ self.serializable_hash
12
13
  end
13
14
  end
14
15
  end
15
16
  end
17
+ # :nocov:
16
18
 
17
19
  # Alias for convenience.
18
20
  # rubocop:disable Layout/LineLength
@@ -4,7 +4,7 @@ class RESTFramework::Serializers::BaseSerializer
4
4
  attr_accessor :object
5
5
 
6
6
  # Accept/ignore `*args` to be compatible with the `ActiveModel::Serializer#initialize` signature.
7
- def initialize(object=nil, *args, controller: nil, **kwargs)
7
+ def initialize(object = nil, *args, controller: nil, **kwargs)
8
8
  @object = object
9
9
  @controller = controller
10
10
  end
@@ -16,24 +16,26 @@ class RESTFramework::Serializers::BaseSerializer
16
16
  end
17
17
 
18
18
  # Synonym for `serialize` for compatibility with `active_model_serializers`.
19
+ # :nocov:
19
20
  def serializable_hash(*args)
20
- return self.serialize(*args)
21
+ self.serialize(*args)
21
22
  end
22
23
 
23
24
  # For compatibility with `active_model_serializers`.
24
25
  def self.cache_enabled?
25
- return false
26
+ false
26
27
  end
27
28
 
28
29
  # For compatibility with `active_model_serializers`.
29
30
  def self.fragment_cache_enabled?
30
- return false
31
+ false
31
32
  end
32
33
 
33
34
  # For compatibility with `active_model_serializers`.
34
35
  def associations(*args, **kwargs)
35
- return []
36
+ []
36
37
  end
38
+ # :nocov:
37
39
  end
38
40
 
39
41
  # Alias for convenience.