rest_framework 1.0.0.rc1 → 1.0.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 +6 -2
- data/VERSION +1 -1
- data/lib/rest_framework/errors/nil_passed_to_render_api_error.rb +1 -1
- data/lib/rest_framework/errors/unknown_model_error.rb +1 -1
- data/lib/rest_framework/filters/ordering_filter.rb +3 -3
- data/lib/rest_framework/filters/query_filter.rb +13 -14
- data/lib/rest_framework/filters/ransack_filter.rb +1 -1
- data/lib/rest_framework/filters/search_filter.rb +3 -3
- data/lib/rest_framework/generators/controller_generator.rb +2 -2
- data/lib/rest_framework/mixins/base_controller_mixin.rb +34 -33
- data/lib/rest_framework/mixins/bulk_model_controller_mixin.rb +8 -15
- data/lib/rest_framework/mixins/model_controller_mixin.rb +42 -35
- data/lib/rest_framework/paginators/page_number_paginator.rb +6 -6
- data/lib/rest_framework/routers.rb +7 -7
- data/lib/rest_framework/serializers/active_model_serializer_adapter_factory.rb +4 -2
- data/lib/rest_framework/serializers/base_serializer.rb +7 -5
- data/lib/rest_framework/serializers/native_serializer.rb +22 -22
- data/lib/rest_framework/utils.rb +21 -21
- data/lib/rest_framework/version.rb +1 -1
- data/lib/rest_framework.rb +9 -9
- metadata +5 -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
|
-
|
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
|
|
@@ -74,7 +74,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
74
74
|
}
|
75
75
|
|
76
76
|
module ClassMethods
|
77
|
-
IGNORE_VALIDATORS_WITH_KEYS = [:if, :unless].freeze
|
77
|
+
IGNORE_VALIDATORS_WITH_KEYS = [ :if, :unless ].freeze
|
78
78
|
|
79
79
|
def get_model
|
80
80
|
return @model if @model
|
@@ -91,7 +91,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
91
91
|
|
92
92
|
# Override to include ActiveRecord i18n-translated column names.
|
93
93
|
def label_for(s)
|
94
|
-
|
94
|
+
self.get_model.human_attribute_name(s, default: super)
|
95
95
|
end
|
96
96
|
|
97
97
|
# Get the available fields. Fallback to this controller's model columns, or an empty array. This
|
@@ -121,7 +121,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
121
121
|
input_fields = input_fields.map(&:to_s)
|
122
122
|
end
|
123
123
|
|
124
|
-
|
124
|
+
input_fields
|
125
125
|
end
|
126
126
|
|
127
127
|
# Get a full field configuration, including defaults and inferred values.
|
@@ -141,7 +141,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
141
141
|
.select { |n| n.to_s.start_with?("rich_text_") }
|
142
142
|
attachment_reflections = model.attachment_reflections
|
143
143
|
|
144
|
-
|
144
|
+
@field_configuration = self.get_fields.map { |f|
|
145
145
|
cfg = field_config[f]&.dup || {}
|
146
146
|
cfg[:label] ||= self.label_for(f)
|
147
147
|
|
@@ -218,7 +218,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
218
218
|
v[:kind] = "method"
|
219
219
|
end
|
220
220
|
|
221
|
-
next [sf, v]
|
221
|
+
next [ sf, v ]
|
222
222
|
}.to_h.compact.presence
|
223
223
|
|
224
224
|
# Determine if we render id/ids fields. Unfortunately, `has_one` does not provide this
|
@@ -231,7 +231,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
231
231
|
if self.permit_nested_attributes_assignment && (
|
232
232
|
nested_opts = model.nested_attributes_options[f.to_sym].presence
|
233
233
|
)
|
234
|
-
cfg[:nested_attributes_options] = {field: "#{f}_attributes", **nested_opts}
|
234
|
+
cfg[:nested_attributes_options] = { field: "#{f}_attributes", **nested_opts }
|
235
235
|
end
|
236
236
|
|
237
237
|
begin
|
@@ -283,7 +283,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
283
283
|
cfg[:validators][kind] << options
|
284
284
|
end
|
285
285
|
|
286
|
-
next [f, cfg]
|
286
|
+
next [ f, cfg ]
|
287
287
|
}.to_h.with_indifferent_access
|
288
288
|
end
|
289
289
|
|
@@ -295,7 +295,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
295
295
|
required: field_configuration.select { |_, cfg| cfg[:required] }.keys,
|
296
296
|
type: "object",
|
297
297
|
properties: field_configuration.map { |f, cfg|
|
298
|
-
v = {title: cfg[:label]}
|
298
|
+
v = { title: cfg[:label] }
|
299
299
|
|
300
300
|
if cfg[:kind] == "association"
|
301
301
|
v[:type] = cfg[:reflection].collection? ? "array" : "object"
|
@@ -324,7 +324,14 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
324
324
|
v[:"x-rrf-kind"] = cfg[:kind] if cfg[:kind]
|
325
325
|
|
326
326
|
if cfg[:reflection]
|
327
|
-
v[:"x-rrf-reflection"] =
|
327
|
+
v[:"x-rrf-reflection"] = {
|
328
|
+
class_name: cfg[:reflection].class_name,
|
329
|
+
foreign_key: cfg[:reflection].foreign_key,
|
330
|
+
association_foreign_key: cfg[:reflection].association_foreign_key,
|
331
|
+
association_primary_key: cfg[:reflection].association_primary_key,
|
332
|
+
inverse_of: cfg[:reflection].inverse_of&.name,
|
333
|
+
join_table: cfg[:reflection].join_table,
|
334
|
+
}.compact
|
328
335
|
v[:"x-rrf-association_pk"] = cfg[:association_pk]
|
329
336
|
v[:"x-rrf-sub_fields"] = cfg[:sub_fields]
|
330
337
|
v[:"x-rrf-sub_fields_metadata"] = cfg[:sub_fields_metadata]
|
@@ -332,15 +339,15 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
332
339
|
v[:"x-rrf-nested_attributes_options"] = cfg[:nested_attributes_options]
|
333
340
|
end
|
334
341
|
|
335
|
-
next [f, v]
|
342
|
+
next [ f, v ]
|
336
343
|
}.to_h,
|
337
344
|
}
|
338
345
|
|
339
|
-
|
346
|
+
@openapi_schema
|
340
347
|
end
|
341
348
|
|
342
349
|
def openapi_schema_name
|
343
|
-
|
350
|
+
@openapi_schema_name ||= self.name.chomp("Controller").gsub("::", ".")
|
344
351
|
end
|
345
352
|
|
346
353
|
def openapi_paths(_routes, tag)
|
@@ -358,7 +365,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
358
365
|
if !extra_action && method != "options" # rubocop:disable Style/Next
|
359
366
|
# Add schema to request body content types.
|
360
367
|
action.dig(:requestBody, :content)&.each do |_t, v|
|
361
|
-
v[:schema] = {"$ref" => "#/components/schemas/#{schema_name}"}
|
368
|
+
v[:schema] = { "$ref" => "#/components/schemas/#{schema_name}" }
|
362
369
|
end
|
363
370
|
|
364
371
|
# Add schema to successful response body content types.
|
@@ -368,7 +375,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
368
375
|
response[:content]&.each do |t, v|
|
369
376
|
next if t == "text/html"
|
370
377
|
|
371
|
-
v[:schema] = {"$ref" => "#/components/schemas/#{schema_name}"}
|
378
|
+
v[:schema] = { "$ref" => "#/components/schemas/#{schema_name}" }
|
372
379
|
end
|
373
380
|
end
|
374
381
|
|
@@ -385,7 +392,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
385
392
|
end
|
386
393
|
end
|
387
394
|
|
388
|
-
|
395
|
+
paths
|
389
396
|
end
|
390
397
|
|
391
398
|
def openapi_document(request, route_group_name, _routes)
|
@@ -396,7 +403,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
396
403
|
document[:components][:schemas] ||= {}
|
397
404
|
document[:components][:schemas][self.openapi_schema_name] = self.openapi_schema
|
398
405
|
|
399
|
-
|
406
|
+
document.merge(
|
400
407
|
{
|
401
408
|
"x-rrf-primary_key" => self.get_model.primary_key,
|
402
409
|
"x-rrf-callbacks" => self._process_action_callbacks.as_json,
|
@@ -471,7 +478,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
471
478
|
end
|
472
479
|
|
473
480
|
def get_fields
|
474
|
-
|
481
|
+
self.class.get_fields(input_fields: self.class.fields)
|
475
482
|
end
|
476
483
|
|
477
484
|
# Get a hash of strong parameters for the current action.
|
@@ -520,7 +527,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
520
527
|
# TODO: Consider adjusting this based on `nested_attributes_options`.
|
521
528
|
if self.class.permit_nested_attributes_assignment
|
522
529
|
hash_variations["#{f}_attributes"] = (
|
523
|
-
config[:sub_fields] + ["_destroy"]
|
530
|
+
config[:sub_fields] + [ "_destroy" ]
|
524
531
|
)
|
525
532
|
end
|
526
533
|
|
@@ -534,11 +541,11 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
534
541
|
@_get_allowed_parameters += variations
|
535
542
|
@_get_allowed_parameters << hash_variations
|
536
543
|
|
537
|
-
|
544
|
+
@_get_allowed_parameters
|
538
545
|
end
|
539
546
|
|
540
547
|
def get_serializer_class
|
541
|
-
|
548
|
+
super || RESTFramework::NativeSerializer
|
542
549
|
end
|
543
550
|
|
544
551
|
# Use strong parameters to filter the request body.
|
@@ -610,8 +617,8 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
610
617
|
body_params = if allowed_params == true
|
611
618
|
ActionController::Parameters.new(data).permit!
|
612
619
|
elsif bulk_mode
|
613
|
-
pk = bulk_mode == :update ? [pk] : []
|
614
|
-
ActionController::Parameters.new(data).permit({_json: allowed_params + pk})
|
620
|
+
pk = bulk_mode == :update ? [ pk ] : []
|
621
|
+
ActionController::Parameters.new(data).permit({ _json: allowed_params + pk })
|
615
622
|
else
|
616
623
|
ActionController::Parameters.new(data).permit(*allowed_params)
|
617
624
|
end
|
@@ -633,7 +640,7 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
633
640
|
# Filter fields in `exclude_body_fields`.
|
634
641
|
(self.class.exclude_body_fields || []).each { |f| body_params.delete(f) }
|
635
642
|
|
636
|
-
|
643
|
+
body_params
|
637
644
|
end
|
638
645
|
alias_method :get_create_params, :get_body_params
|
639
646
|
alias_method :get_update_params, :get_body_params
|
@@ -647,14 +654,14 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
647
654
|
return model.all
|
648
655
|
end
|
649
656
|
|
650
|
-
|
657
|
+
nil
|
651
658
|
end
|
652
659
|
|
653
660
|
# Filter the recordset and return records this request has access to.
|
654
661
|
def get_records
|
655
662
|
data = self.get_recordset
|
656
663
|
|
657
|
-
|
664
|
+
@records ||= self.class.filter_backends&.reduce(data) { |d, filter|
|
658
665
|
filter.new(controller: self).filter_data(d)
|
659
666
|
} || data
|
660
667
|
end
|
@@ -687,9 +694,9 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
687
694
|
|
688
695
|
# Return the record. Route key is always `:id` by Rails' convention.
|
689
696
|
if is_pk
|
690
|
-
|
697
|
+
@record = collection.find(request.path_parameters[:id])
|
691
698
|
else
|
692
|
-
|
699
|
+
@record = collection.find_by!(find_by_key => request.path_parameters[:id])
|
693
700
|
end
|
694
701
|
end
|
695
702
|
|
@@ -713,8 +720,8 @@ module RESTFramework::Mixins::BaseModelControllerMixin
|
|
713
720
|
# the serializer directly. This would fail for active model serializers, but maybe we don't
|
714
721
|
# care?
|
715
722
|
s = RESTFramework::Utils.wrap_ams(self.get_serializer_class)
|
716
|
-
|
717
|
-
s.new(record, controller: self).serialize.merge!({errors: record.errors.presence}.compact)
|
723
|
+
records.map do |record|
|
724
|
+
s.new(record, controller: self).serialize.merge!({ errors: record.errors.presence }.compact)
|
718
725
|
end
|
719
726
|
end
|
720
727
|
end
|
@@ -743,7 +750,7 @@ module RESTFramework::Mixins::ListModelMixin
|
|
743
750
|
end
|
744
751
|
end
|
745
752
|
|
746
|
-
|
753
|
+
records
|
747
754
|
end
|
748
755
|
end
|
749
756
|
|
@@ -762,7 +769,7 @@ module RESTFramework::Mixins::CreateModelMixin
|
|
762
769
|
|
763
770
|
# Perform the `create!` call and return the created record.
|
764
771
|
def create!
|
765
|
-
|
772
|
+
self.get_create_from.create!(self.get_create_params)
|
766
773
|
end
|
767
774
|
end
|
768
775
|
|
@@ -776,7 +783,7 @@ module RESTFramework::Mixins::UpdateModelMixin
|
|
776
783
|
def update!
|
777
784
|
record = self.get_record
|
778
785
|
record.update!(self.get_update_params)
|
779
|
-
|
786
|
+
record
|
780
787
|
end
|
781
788
|
end
|
782
789
|
|
@@ -789,7 +796,7 @@ module RESTFramework::Mixins::DestroyModelMixin
|
|
789
796
|
|
790
797
|
# Perform the `destroy!` call and return the destroyed (and frozen) record.
|
791
798
|
def destroy!
|
792
|
-
|
799
|
+
self.get_record.destroy!
|
793
800
|
end
|
794
801
|
end
|
795
802
|
|
@@ -34,11 +34,11 @@ class RESTFramework::Paginators::PageNumberPaginator < RESTFramework::Paginators
|
|
34
34
|
end
|
35
35
|
|
36
36
|
# Ensure we return at least 1.
|
37
|
-
|
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
|
-
|
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
|
-
|
72
|
+
{
|
73
73
|
count: @count,
|
74
74
|
page: @page_number,
|
75
75
|
page_size: @page_size,
|
@@ -43,7 +43,7 @@ module ActionDispatch::Routing
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
|
46
|
+
controller
|
47
47
|
end
|
48
48
|
|
49
49
|
# Interal interface for routing extra actions.
|
@@ -114,7 +114,7 @@ module ActionDispatch::Routing
|
|
114
114
|
RESTFramework::RRF_BUILTIN_ACTIONS.each do |action, methods|
|
115
115
|
next unless controller_class.method_defined?(action)
|
116
116
|
|
117
|
-
[methods].flatten.each do |m|
|
117
|
+
[ methods ].flatten.each do |m|
|
118
118
|
public_send(m, "", action: action) if self.respond_to?(m)
|
119
119
|
end
|
120
120
|
end
|
@@ -123,7 +123,7 @@ module ActionDispatch::Routing
|
|
123
123
|
RESTFramework::RRF_BUILTIN_BULK_ACTIONS.each do |action, methods|
|
124
124
|
next unless controller_class.method_defined?(action)
|
125
125
|
|
126
|
-
[methods].flatten.each do |m|
|
126
|
+
[ methods ].flatten.each do |m|
|
127
127
|
public_send(m, "", action: action) if self.respond_to?(m)
|
128
128
|
end
|
129
129
|
end
|
@@ -154,7 +154,7 @@ module ActionDispatch::Routing
|
|
154
154
|
end
|
155
155
|
|
156
156
|
# Route a controller without the default resourceful paths.
|
157
|
-
def rest_route(name=nil, **kwargs, &block)
|
157
|
+
def rest_route(name = nil, **kwargs, &block)
|
158
158
|
controller = kwargs.delete(:controller) || name
|
159
159
|
route_root_to = kwargs.delete(:route_root_to)
|
160
160
|
if controller.is_a?(Class)
|
@@ -184,7 +184,7 @@ module ActionDispatch::Routing
|
|
184
184
|
RESTFramework::RRF_BUILTIN_ACTIONS.each do |action, methods|
|
185
185
|
next unless controller_class.method_defined?(action)
|
186
186
|
|
187
|
-
[methods].flatten.each do |m|
|
187
|
+
[ methods ].flatten.each do |m|
|
188
188
|
public_send(m, "", action: action) if self.respond_to?(m)
|
189
189
|
end
|
190
190
|
end
|
@@ -201,7 +201,7 @@ module ActionDispatch::Routing
|
|
201
201
|
end
|
202
202
|
|
203
203
|
# Route a controller's `#root` to '/' in the current scope/namespace, along with other actions.
|
204
|
-
def rest_root(name=nil, **kwargs, &block)
|
204
|
+
def rest_root(name = nil, **kwargs, &block)
|
205
205
|
# By default, use RootController#root.
|
206
206
|
root_action = kwargs.delete(:action) || :root
|
207
207
|
controller = kwargs.delete(:controller) || name || :root
|
@@ -211,7 +211,7 @@ module ActionDispatch::Routing
|
|
211
211
|
kwargs[:path] = ""
|
212
212
|
end
|
213
213
|
|
214
|
-
|
214
|
+
rest_route(controller, route_root_to: root_action, **kwargs) do
|
215
215
|
yield if block_given?
|
216
216
|
end
|
217
217
|
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
|
-
|
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
|
-
|
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
|
-
|
21
|
+
self.serialize(*args)
|
21
22
|
end
|
22
23
|
|
23
24
|
# For compatibility with `active_model_serializers`.
|
24
25
|
def self.cache_enabled?
|
25
|
-
|
26
|
+
false
|
26
27
|
end
|
27
28
|
|
28
29
|
# For compatibility with `active_model_serializers`.
|
29
30
|
def self.fragment_cache_enabled?
|
30
|
-
|
31
|
+
false
|
31
32
|
end
|
32
33
|
|
33
34
|
# For compatibility with `active_model_serializers`.
|
34
35
|
def associations(*args, **kwargs)
|
35
|
-
|
36
|
+
[]
|
36
37
|
end
|
38
|
+
# :nocov:
|
37
39
|
end
|
38
40
|
|
39
41
|
# Alias for convenience.
|
@@ -7,7 +7,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
7
7
|
class_attribute :action_config
|
8
8
|
|
9
9
|
# Accept/ignore `*args` to be compatible with the `ActiveModel::Serializer#initialize` signature.
|
10
|
-
def initialize(object=nil, *args, many: nil, model: nil, **kwargs)
|
10
|
+
def initialize(object = nil, *args, many: nil, model: nil, **kwargs)
|
11
11
|
super(object, *args, **kwargs)
|
12
12
|
|
13
13
|
if many.nil?
|
@@ -28,7 +28,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
28
28
|
|
29
29
|
# Get controller action, if possible.
|
30
30
|
def get_action
|
31
|
-
|
31
|
+
@controller&.action_name&.to_sym
|
32
32
|
end
|
33
33
|
|
34
34
|
# Get a locally defined native serializer configuration, if one is defined.
|
@@ -47,7 +47,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
47
47
|
return self.singular_config if @many == false && self.singular_config
|
48
48
|
|
49
49
|
# Lastly, try returning the default config, or singular/plural config in that order.
|
50
|
-
|
50
|
+
self.config || self.singular_config || self.plural_config
|
51
51
|
end
|
52
52
|
|
53
53
|
# Get a native serializer configuration from the controller.
|
@@ -60,7 +60,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
60
60
|
controller_serializer = @controller.class.native_serializer_singular_config
|
61
61
|
end
|
62
62
|
|
63
|
-
|
63
|
+
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
|
@@ -99,7 +99,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
99
99
|
subcfg = subcfg.to_sym
|
100
100
|
|
101
101
|
if add
|
102
|
-
subcfg = subcfg.in?(fields) ? fields : [subcfg, *fields]
|
102
|
+
subcfg = subcfg.in?(fields) ? fields : [ subcfg, *fields ]
|
103
103
|
elsif only
|
104
104
|
subcfg = subcfg.in?(fields) ? subcfg : []
|
105
105
|
else
|
@@ -107,7 +107,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
|
-
|
110
|
+
subcfg
|
111
111
|
end
|
112
112
|
|
113
113
|
# Filter out configuration properties based on the :except/:only query parameters.
|
@@ -153,7 +153,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
|
-
|
156
|
+
cfg
|
157
157
|
end
|
158
158
|
|
159
159
|
# Get the associations limit from the controller.
|
@@ -174,7 +174,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
174
174
|
end
|
175
175
|
end
|
176
176
|
|
177
|
-
|
177
|
+
@_get_associations_limit = limit
|
178
178
|
end
|
179
179
|
|
180
180
|
# Get a serializer configuration from the controller. `@controller` and `@model` must be set.
|
@@ -210,7 +210,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
210
210
|
sub_methods << sf
|
211
211
|
end
|
212
212
|
end
|
213
|
-
sub_config = {only: sub_columns, methods: sub_methods}
|
213
|
+
sub_config = { only: sub_columns, methods: sub_methods }
|
214
214
|
|
215
215
|
# Apply certain rules regarding collection associations.
|
216
216
|
if ref.collection?
|
@@ -257,7 +257,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
257
257
|
# ActiveStorage Integration: Define attachment serializer method.
|
258
258
|
if ref.macro == :has_one_attached
|
259
259
|
serializer_methods[f] = f
|
260
|
-
includes_map[f] = {"#{f}_attachment": :blob}
|
260
|
+
includes_map[f] = { "#{f}_attachment": :blob }
|
261
261
|
self.define_singleton_method(f) do |record|
|
262
262
|
attached = record.send(f)
|
263
263
|
next attached.attachment ? {
|
@@ -268,7 +268,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
268
268
|
end
|
269
269
|
elsif ref.macro == :has_many_attached
|
270
270
|
serializer_methods[f] = f
|
271
|
-
includes_map[f] = {"#{f}_attachments": :blob}
|
271
|
+
includes_map[f] = { "#{f}_attachments": :blob }
|
272
272
|
self.define_singleton_method(f) do |record|
|
273
273
|
# Iterating the collection yields attachment objects.
|
274
274
|
next record.send(f).map { |a|
|
@@ -288,7 +288,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
288
288
|
end
|
289
289
|
end
|
290
290
|
|
291
|
-
|
291
|
+
{
|
292
292
|
only: columns,
|
293
293
|
include: includes,
|
294
294
|
methods: methods,
|
@@ -317,24 +317,24 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
317
317
|
end
|
318
318
|
|
319
319
|
# By default, pass an empty configuration, using the default Rails serializer.
|
320
|
-
|
320
|
+
{}
|
321
321
|
end
|
322
322
|
|
323
323
|
# Get a configuration passable to `serializable_hash` for the object, filtered if required.
|
324
324
|
def get_serializer_config
|
325
|
-
|
325
|
+
self.filter_from_request(self.get_raw_serializer_config)
|
326
326
|
end
|
327
327
|
|
328
328
|
# Serialize a single record and merge results of `serializer_methods`.
|
329
329
|
def _serialize(record, config, serializer_methods)
|
330
330
|
# Ensure serializer_methods is either falsy, or a hash.
|
331
331
|
if serializer_methods && !serializer_methods.is_a?(Hash)
|
332
|
-
serializer_methods = [serializer_methods].flatten.map { |m| [m, m] }.to_h
|
332
|
+
serializer_methods = [ serializer_methods ].flatten.map { |m| [ m, m ] }.to_h
|
333
333
|
end
|
334
334
|
|
335
335
|
# Merge serialized record with any serializer method results.
|
336
|
-
|
337
|
-
serializer_methods&.map { |m, k| [k.to_sym, self.send(m, record)] }.to_h,
|
336
|
+
record.serializable_hash(config).merge(
|
337
|
+
serializer_methods&.map { |m, k| [ k.to_sym, self.send(m, record) ] }.to_h,
|
338
338
|
)
|
339
339
|
end
|
340
340
|
|
@@ -352,29 +352,29 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
|
|
352
352
|
return @object.map { |r| self._serialize(r, config, serializer_methods) }
|
353
353
|
end
|
354
354
|
|
355
|
-
|
355
|
+
self._serialize(@object, config, serializer_methods)
|
356
356
|
end
|
357
357
|
|
358
358
|
# Allow a serializer instance to be used as a hash directly in a nested serializer config.
|
359
359
|
def [](key)
|
360
360
|
@_nested_config ||= self.get_serializer_config
|
361
|
-
|
361
|
+
@_nested_config[key]
|
362
362
|
end
|
363
363
|
|
364
364
|
def []=(key, value)
|
365
365
|
@_nested_config ||= self.get_serializer_config
|
366
|
-
|
366
|
+
@_nested_config[key] = value
|
367
367
|
end
|
368
368
|
|
369
369
|
# Allow a serializer class to be used as a hash directly in a nested serializer config.
|
370
370
|
def self.[](key)
|
371
371
|
@_nested_config ||= self.new.get_serializer_config
|
372
|
-
|
372
|
+
@_nested_config[key]
|
373
373
|
end
|
374
374
|
|
375
375
|
def self.[]=(key, value)
|
376
376
|
@_nested_config ||= self.new.get_serializer_config
|
377
|
-
|
377
|
+
@_nested_config[key] = value
|
378
378
|
end
|
379
379
|
end
|
380
380
|
|