rest_framework 0.1.0 → 0.2.2
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 +14 -8
- data/lib/rest_framework.rb +3 -0
- data/lib/rest_framework/VERSION_STAMP +1 -1
- data/lib/rest_framework/controller_mixins.rb +4 -0
- data/lib/rest_framework/controller_mixins/base.rb +154 -159
- data/lib/rest_framework/controller_mixins/models.rb +215 -176
- data/lib/rest_framework/errors.rb +26 -0
- data/lib/rest_framework/filters.rb +53 -50
- data/lib/rest_framework/generators.rb +5 -0
- data/lib/rest_framework/generators/controller_generator.rb +26 -0
- data/lib/rest_framework/paginators.rb +76 -65
- data/lib/rest_framework/routers.rb +10 -4
- data/lib/rest_framework/serializers.rb +133 -84
- data/lib/rest_framework/version.rb +11 -9
- metadata +5 -2
@@ -0,0 +1,26 @@
|
|
1
|
+
# Top-level class for all REST Framework errors.
|
2
|
+
class RESTFramework::Error < StandardError
|
3
|
+
end
|
4
|
+
|
5
|
+
class RESTFramework::NilPassedToAPIResponseError < RESTFramework::Error
|
6
|
+
def message
|
7
|
+
return <<~MSG.split("\n").join(' ')
|
8
|
+
Payload of `nil` was passed to `api_response`; this is unsupported. If you want a blank
|
9
|
+
response, pass `''` (an empty string) as the payload. If this was the result of a `find_by`
|
10
|
+
(or similar Active Record method) not finding a record, you should use the bang version (e.g.,
|
11
|
+
`find_by!`) to raise `ActiveRecord::RecordNotFound`, which the REST controller will catch and
|
12
|
+
return an appropriate error response.
|
13
|
+
MSG
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class RESTFramework::UnserializableError < RESTFramework::Error
|
18
|
+
def initialize(object)
|
19
|
+
@object = object
|
20
|
+
return super
|
21
|
+
end
|
22
|
+
|
23
|
+
def message
|
24
|
+
return "Unable to serialize `#{@object.inspect}` (of type `#{@object.class}`)."
|
25
|
+
end
|
26
|
+
end
|
@@ -1,65 +1,68 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
end
|
1
|
+
class RESTFramework::BaseFilter
|
2
|
+
def initialize(controller:)
|
3
|
+
@controller = controller
|
4
|
+
end
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
end
|
6
|
+
def get_filtered_data(data)
|
7
|
+
raise NotImplementedError
|
10
8
|
end
|
9
|
+
end
|
11
10
|
|
12
|
-
# A simple filtering backend that supports filtering a recordset based on fields defined on the
|
13
|
-
# controller class.
|
14
|
-
class ModelFilter < BaseFilter
|
15
|
-
# Filter params for keys allowed by the current action's filterset_fields/fields config.
|
16
|
-
def _get_filter_params
|
17
|
-
fields = @controller.class.filterset_fields || @controller.send(:get_fields)
|
18
|
-
return @controller.request.query_parameters.select { |p|
|
19
|
-
fields.include?(p.to_sym) || fields.include?(p.to_s)
|
20
|
-
}.to_hash.symbolize_keys
|
21
|
-
end
|
22
11
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
12
|
+
# A simple filtering backend that supports filtering a recordset based on fields defined on the
|
13
|
+
# controller class.
|
14
|
+
class RESTFramework::ModelFilter < RESTFramework::BaseFilter
|
15
|
+
# Filter params for keys allowed by the current action's filterset_fields/fields config.
|
16
|
+
def _get_filter_params
|
17
|
+
fields = @controller.class.filterset_fields&.map(&:to_s) || @controller.send(:get_fields)
|
18
|
+
return @controller.request.query_parameters.select { |p|
|
19
|
+
fields.include?(p)
|
20
|
+
}.to_h.symbolize_keys # convert from HashWithIndifferentAccess to Hash w/keys
|
21
|
+
end
|
28
22
|
|
29
|
-
|
23
|
+
# Filter data according to the request query parameters.
|
24
|
+
def get_filtered_data(data)
|
25
|
+
filter_params = self._get_filter_params
|
26
|
+
unless filter_params.blank?
|
27
|
+
return data.where(**filter_params)
|
30
28
|
end
|
29
|
+
|
30
|
+
return data
|
31
31
|
end
|
32
|
+
end
|
32
33
|
|
33
|
-
# A filter backend which handles ordering of the recordset.
|
34
|
-
class ModelOrderingFilter < BaseFilter
|
35
|
-
# Convert ordering string to an ordering configuration.
|
36
|
-
def _get_ordering
|
37
|
-
return nil unless @controller.class.ordering_query_param
|
38
34
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
else
|
45
|
-
[field.to_sym, :asc]
|
46
|
-
end
|
47
|
-
}.to_h
|
48
|
-
end
|
35
|
+
# A filter backend which handles ordering of the recordset.
|
36
|
+
class RESTFramework::ModelOrderingFilter < RESTFramework::BaseFilter
|
37
|
+
# Convert ordering string to an ordering configuration.
|
38
|
+
def _get_ordering
|
39
|
+
return nil unless @controller.class.ordering_query_param
|
49
40
|
|
50
|
-
|
41
|
+
order_string = @controller.params[@controller.class.ordering_query_param]
|
42
|
+
unless order_string.blank?
|
43
|
+
return order_string.split(',').map { |field|
|
44
|
+
if field[0] == '-'
|
45
|
+
[field[1..-1].to_sym, :desc]
|
46
|
+
else
|
47
|
+
[field.to_sym, :asc]
|
48
|
+
end
|
49
|
+
}.to_h
|
51
50
|
end
|
52
51
|
|
53
|
-
|
54
|
-
ordering = self._get_ordering
|
55
|
-
if ordering && !ordering.empty?
|
56
|
-
return data.order(_get_ordering)
|
57
|
-
end
|
58
|
-
return data
|
59
|
-
end
|
52
|
+
return nil
|
60
53
|
end
|
61
54
|
|
62
|
-
#
|
63
|
-
|
64
|
-
|
55
|
+
# Order data according to the request query parameters.
|
56
|
+
def get_filtered_data(data)
|
57
|
+
ordering = self._get_ordering
|
58
|
+
if ordering && !ordering.empty?
|
59
|
+
return data.order(_get_ordering)
|
60
|
+
end
|
61
|
+
return data
|
62
|
+
end
|
65
63
|
end
|
64
|
+
|
65
|
+
|
66
|
+
# TODO: implement searching within fields rather than exact match filtering (ModelFilter)
|
67
|
+
# class RESTFramework::ModelSearchFilter < RESTFramework::BaseFilter
|
68
|
+
# end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
|
4
|
+
class RESTFramework::Generators::ControllerGenerator < Rails::Generators::Base
|
5
|
+
desc <<~END
|
6
|
+
Description:
|
7
|
+
Stubs out a active_scaffolded controller. Pass the model name,
|
8
|
+
either CamelCased or under_scored.
|
9
|
+
The controller name is retrieved as a pluralized version of the model
|
10
|
+
name.
|
11
|
+
To create a controller within a module, specify the model name as a
|
12
|
+
path like 'parent_module/controller_name'.
|
13
|
+
This generates a controller class in app/controllers and invokes helper,
|
14
|
+
template engine and test framework generators.
|
15
|
+
Example:
|
16
|
+
`rails generate rest_framework:controller CreditCard`
|
17
|
+
Credit card controller with URLs like /credit_card/debit.
|
18
|
+
Controller: app/controllers/credit_cards_controller.rb
|
19
|
+
Functional Test: test/functional/credit_cards_controller_test.rb
|
20
|
+
Helper: app/helpers/credit_cards_helper.rb
|
21
|
+
END
|
22
|
+
|
23
|
+
def create_controller_file
|
24
|
+
create_file "app/controllers/some_controller.rb", "# Add initialization content here"
|
25
|
+
end
|
26
|
+
end
|
@@ -1,84 +1,95 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
class PageNumberPaginator
|
7
|
-
def initialize(data:, controller:, **kwargs)
|
8
|
-
@data = data
|
9
|
-
@controller = controller
|
10
|
-
@count = data.count
|
11
|
-
@page_size = self._page_size
|
12
|
-
|
13
|
-
@total_pages = @count / @page_size
|
14
|
-
@total_pages += 1 if (@count % @page_size != 0)
|
15
|
-
end
|
1
|
+
class RESTFramework::BasePaginator
|
2
|
+
def initialize(data:, controller:, **kwargs)
|
3
|
+
@data = data
|
4
|
+
@controller = controller
|
5
|
+
end
|
16
6
|
|
17
|
-
|
18
|
-
|
7
|
+
# Get the page and return it so the caller can serialize it.
|
8
|
+
def get_page
|
9
|
+
raise NotImplementedError
|
10
|
+
end
|
19
11
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
12
|
+
# Wrap the serialized page with appropriate metadata.
|
13
|
+
def get_paginated_response(serialized_page)
|
14
|
+
raise NotImplementedError
|
15
|
+
end
|
16
|
+
end
|
27
17
|
|
28
|
-
# Otherwise, get from config.
|
29
|
-
if !page_size && @controller.class.page_size
|
30
|
-
page_size = @controller.class.page_size
|
31
|
-
end
|
32
18
|
|
33
|
-
|
34
|
-
|
19
|
+
# A simple paginator based on page numbers.
|
20
|
+
#
|
21
|
+
# Example: http://example.com/api/users/?page=3&page_size=50
|
22
|
+
class RESTFramework::PageNumberPaginator < RESTFramework::BasePaginator
|
23
|
+
def initialize(**kwargs)
|
24
|
+
super
|
25
|
+
@count = @data.count
|
26
|
+
@page_size = self._page_size
|
27
|
+
|
28
|
+
@total_pages = @count / @page_size
|
29
|
+
@total_pages += 1 if (@count % @page_size != 0)
|
30
|
+
end
|
31
|
+
|
32
|
+
def _page_size
|
33
|
+
page_size = nil
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
# Get from context, if allowed.
|
36
|
+
if @controller.class.page_size_query_param
|
37
|
+
if page_size = @controller.params[@controller.class.page_size_query_param].presence
|
38
|
+
page_size = page_size.to_i
|
39
39
|
end
|
40
|
+
end
|
40
41
|
|
41
|
-
|
42
|
-
|
42
|
+
# Otherwise, get from config.
|
43
|
+
if !page_size && @controller.class.page_size
|
44
|
+
page_size = @controller.class.page_size
|
43
45
|
end
|
44
46
|
|
45
|
-
|
46
|
-
|
47
|
+
# Ensure we don't exceed the max page size.
|
48
|
+
if @controller.class.max_page_size && page_size > @controller.class.max_page_size
|
49
|
+
page_size = @controller.class.max_page_size
|
47
50
|
end
|
48
51
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
52
|
+
# Ensure we return at least 1.
|
53
|
+
return page_size.zero? ? 1 : page_size
|
54
|
+
end
|
55
|
+
|
56
|
+
def _page_query_param
|
57
|
+
return @controller.class.page_query_param&.to_sym
|
58
|
+
end
|
59
|
+
|
60
|
+
# Get the page and return it so the caller can serialize it.
|
61
|
+
def get_page(page_number=nil)
|
62
|
+
# If page number isn't provided, infer from the params or use 1 as a fallback value.
|
63
|
+
if !page_number
|
64
|
+
page_number = @controller&.params&.[](self._page_query_param)
|
65
|
+
if page_number.blank?
|
66
|
+
page_number = 1
|
67
|
+
else
|
68
|
+
page_number = page_number.to_i
|
69
|
+
if page_number.zero?
|
54
70
|
page_number = 1
|
55
|
-
else
|
56
|
-
page_number = page_number.to_i
|
57
|
-
if page_number.zero?
|
58
|
-
page_number = 1
|
59
|
-
end
|
60
71
|
end
|
61
72
|
end
|
62
|
-
@page_number = page_number
|
63
|
-
|
64
|
-
# Get the data page and return it so the caller can serialize the data in the proper format.
|
65
|
-
page_index = @page_number - 1
|
66
|
-
return @data.limit(@page_size).offset(page_index * @page_size)
|
67
73
|
end
|
74
|
+
@page_number = page_number
|
68
75
|
|
69
|
-
#
|
70
|
-
|
71
|
-
|
72
|
-
count: @count,
|
73
|
-
page: @page_number,
|
74
|
-
total_pages: @total_pages,
|
75
|
-
results: serialized_page,
|
76
|
-
}
|
77
|
-
end
|
76
|
+
# Get the data page and return it so the caller can serialize the data in the proper format.
|
77
|
+
page_index = @page_number - 1
|
78
|
+
return @data.limit(@page_size).offset(page_index * @page_size)
|
78
79
|
end
|
79
80
|
|
80
|
-
# TODO:
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
# Wrap the serialized page with appropriate metadata. TODO: include links.
|
82
|
+
def get_paginated_response(serialized_page)
|
83
|
+
return {
|
84
|
+
count: @count,
|
85
|
+
page: @page_number,
|
86
|
+
total_pages: @total_pages,
|
87
|
+
results: serialized_page,
|
88
|
+
}
|
89
|
+
end
|
84
90
|
end
|
91
|
+
|
92
|
+
|
93
|
+
# TODO: implement this
|
94
|
+
# class RESTFramework::CountOffsetPaginator
|
95
|
+
# end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'action_dispatch/routing/mapper'
|
2
2
|
|
3
|
+
|
3
4
|
module ActionDispatch::Routing
|
4
5
|
class Mapper
|
5
|
-
#
|
6
|
+
# Internal helper to take extra_actions hash and convert to a consistent format.
|
6
7
|
protected def _parse_extra_actions(extra_actions)
|
7
8
|
return (extra_actions || {}).map do |k,v|
|
8
9
|
kwargs = {}
|
@@ -24,6 +25,11 @@ module ActionDispatch::Routing
|
|
24
25
|
path = v.delete(:path)
|
25
26
|
end
|
26
27
|
|
28
|
+
# Set the action to be the action key unless it's already defined.
|
29
|
+
if !kwargs[:action]
|
30
|
+
kwargs[:action] = k
|
31
|
+
end
|
32
|
+
|
27
33
|
# Pass any further kwargs to the underlying Rails interface.
|
28
34
|
kwargs = kwargs.merge(v)
|
29
35
|
elsif v.is_a?(Symbol) || v.is_a?(String)
|
@@ -37,7 +43,7 @@ module ActionDispatch::Routing
|
|
37
43
|
end
|
38
44
|
end
|
39
45
|
|
40
|
-
#
|
46
|
+
# Internal interface to get the controller class from the name and current scope.
|
41
47
|
protected def _get_controller_class(name, pluralize: true, fallback_reverse_pluralization: true)
|
42
48
|
# get class name
|
43
49
|
name = name.to_s.camelize # camelize to leave plural names plural
|
@@ -71,7 +77,7 @@ module ActionDispatch::Routing
|
|
71
77
|
return controller
|
72
78
|
end
|
73
79
|
|
74
|
-
#
|
80
|
+
# Internal core implementation of the `rest_resource(s)` router, both singular and plural.
|
75
81
|
# @param default_singular [Boolean] the default plurality of the resource if the plurality is
|
76
82
|
# not otherwise defined by the controller
|
77
83
|
# @param name [Symbol] the resource name, from which path and controller are deduced by default
|
@@ -166,7 +172,7 @@ module ActionDispatch::Routing
|
|
166
172
|
end
|
167
173
|
|
168
174
|
# Route a controller's `#root` to '/' in the current scope/namespace, along with other actions.
|
169
|
-
# @param
|
175
|
+
# @param name [Symbol] the snake_case name of the controller
|
170
176
|
def rest_root(name=nil, **kwargs, &block)
|
171
177
|
# By default, use RootController#root.
|
172
178
|
root_action = kwargs.delete(:action) || :root
|
@@ -1,116 +1,165 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
class RESTFramework::BaseSerializer
|
2
|
+
def initialize(object: nil, controller: nil, **kwargs)
|
3
|
+
@object = object
|
4
|
+
@controller = controller
|
5
|
+
end
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
@controller = controller
|
8
|
-
end
|
7
|
+
def serialize
|
8
|
+
raise NotImplementedError
|
9
9
|
end
|
10
|
+
end
|
10
11
|
|
11
|
-
# This serializer uses `.as_json` to serialize objects. Despite the name, `.as_json` is an
|
12
|
-
# `ActiveModel` method which converts objects to Ruby primitives (with the top-level being either
|
13
|
-
# an array or a hash).
|
14
|
-
class NativeModelSerializer < BaseSerializer
|
15
|
-
class_attribute :config
|
16
|
-
class_attribute :singular_config
|
17
|
-
class_attribute :plural_config
|
18
|
-
class_attribute :action_config
|
19
12
|
|
20
|
-
|
21
|
-
|
13
|
+
# This serializer uses `.serializable_hash` to convert objects to Ruby primitives (with the
|
14
|
+
# top-level being either an array or a hash).
|
15
|
+
class RESTFramework::NativeSerializer < RESTFramework::BaseSerializer
|
16
|
+
class_attribute :config
|
17
|
+
class_attribute :singular_config
|
18
|
+
class_attribute :plural_config
|
19
|
+
class_attribute :action_config
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
else
|
26
|
-
@many = many
|
27
|
-
end
|
21
|
+
def initialize(many: nil, model: nil, **kwargs)
|
22
|
+
super(**kwargs)
|
28
23
|
|
29
|
-
|
24
|
+
if many.nil?
|
25
|
+
# Determine if we are dealing with many objects or just one.
|
26
|
+
@many = @object.is_a?(Enumerable)
|
27
|
+
else
|
28
|
+
@many = many
|
30
29
|
end
|
31
30
|
|
32
|
-
#
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
# Determine model either explicitly, or by inspecting @object or @controller.
|
32
|
+
@model = model
|
33
|
+
@model ||= @object.class if @object.is_a?(ActiveRecord::Base)
|
34
|
+
@model ||= @object[0].class if (
|
35
|
+
@many && @object.is_a?(Enumerable) && @object.is_a?(ActiveRecord::Base)
|
36
|
+
)
|
37
|
+
@model ||= @controller.send(:get_model) if @controller
|
38
|
+
end
|
36
39
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
+
# Get controller action, if possible.
|
41
|
+
def get_action
|
42
|
+
return @controller&.action_name&.to_sym
|
43
|
+
end
|
40
44
|
|
41
|
-
|
42
|
-
|
43
|
-
|
45
|
+
# Get a locally defined native serializer configuration, if one is defined.
|
46
|
+
def get_local_native_serializer_config
|
47
|
+
action = self.get_action
|
44
48
|
|
45
|
-
|
46
|
-
|
49
|
+
if action && self.action_config
|
50
|
+
# Index action should use :list serializer config if :index is not provided.
|
51
|
+
action = :list if action == :index && !self.action_config.key?(:index)
|
47
52
|
|
48
|
-
|
49
|
-
|
50
|
-
|
53
|
+
return self.action_config[action] if self.action_config[action]
|
54
|
+
end
|
55
|
+
|
56
|
+
# No action_config, so try singular/plural config if explicitly instructed to via @many.
|
57
|
+
return self.plural_config if @many == true && self.plural_config
|
58
|
+
return self.singular_config if @many == false && self.singular_config
|
59
|
+
|
60
|
+
# Lastly, try returning the default config, or singular/plural config in that order.
|
61
|
+
return self.config || self.singular_config || self.plural_config
|
62
|
+
end
|
63
|
+
|
64
|
+
# Helper to get a native serializer configuration from the controller.
|
65
|
+
def get_controller_native_serializer_config
|
66
|
+
return nil unless @controller
|
51
67
|
|
52
|
-
|
53
|
-
|
68
|
+
if @many == true
|
69
|
+
controller_serializer = @controller.try(:native_serializer_plural_config)
|
70
|
+
elsif @many == false
|
71
|
+
controller_serializer = @controller.try(:native_serializer_singular_config)
|
54
72
|
end
|
55
73
|
|
56
|
-
|
57
|
-
|
58
|
-
# Return a locally defined serializer config if one is defined.
|
59
|
-
if local_config = self.get_local_serializer_config
|
60
|
-
return local_config
|
61
|
-
end
|
74
|
+
return controller_serializer || @controller.try(:native_serializer_config)
|
75
|
+
end
|
62
76
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
77
|
+
# Get a configuration passable to `serializable_hash` for the object.
|
78
|
+
def get_serializer_config
|
79
|
+
# Return a locally defined serializer config if one is defined.
|
80
|
+
if local_config = self.get_local_native_serializer_config
|
81
|
+
return local_config
|
82
|
+
end
|
67
83
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
84
|
+
# Return a serializer config if one is defined on the controller.
|
85
|
+
if serializer_config = get_controller_native_serializer_config
|
86
|
+
return serializer_config
|
87
|
+
end
|
88
|
+
|
89
|
+
# If the config wasn't determined, build a serializer config from model fields.
|
90
|
+
fields = @controller.send(:get_fields) if @controller
|
91
|
+
if fields
|
92
|
+
if @model
|
93
|
+
columns, methods = fields.partition { |f| f.in?(@model.column_names) }
|
94
|
+
else
|
95
|
+
columns = fields
|
96
|
+
methods = []
|
73
97
|
end
|
74
98
|
|
75
|
-
return {}
|
99
|
+
return {only: columns, methods: methods}
|
76
100
|
end
|
77
101
|
|
78
|
-
#
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
102
|
+
# By default, pass an empty configuration, allowing the serialization of all columns.
|
103
|
+
return {}
|
104
|
+
end
|
105
|
+
|
106
|
+
# Convert the object (record or recordset) to Ruby primitives.
|
107
|
+
def serialize
|
108
|
+
if @object
|
109
|
+
begin
|
110
|
+
if @object.is_a?(Enumerable)
|
111
|
+
return @object.map { |r| r.serializable_hash(self.get_serializer_config) }
|
112
|
+
end
|
113
|
+
return @object.serializable_hash(self.get_serializer_config)
|
114
|
+
rescue NoMethodError
|
83
115
|
end
|
84
|
-
return nil
|
85
116
|
end
|
86
117
|
|
87
|
-
#
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
118
|
+
# Raise an error if we cannot serialize the object.
|
119
|
+
raise RESTFramework::UnserializableError.new(@object)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Allow a serializer instance to be used as a hash directly in a nested serializer config.
|
123
|
+
def [](key)
|
124
|
+
unless instance_variable_defined?(:@_nested_config)
|
125
|
+
@_nested_config = self.get_serializer_config
|
93
126
|
end
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
127
|
+
return @_nested_config[key]
|
128
|
+
end
|
129
|
+
def []=(key, value)
|
130
|
+
unless instance_variable_defined?(:@_nested_config)
|
131
|
+
@_nested_config = self.get_serializer_config
|
99
132
|
end
|
133
|
+
return @_nested_config[key] = value
|
134
|
+
end
|
100
135
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
end
|
106
|
-
return @_nested_config[key]
|
136
|
+
# Allow a serializer class to be used as a hash directly in a nested serializer config.
|
137
|
+
def self.[](key)
|
138
|
+
unless instance_variable_defined?(:@_nested_config)
|
139
|
+
@_nested_config = self.new.get_serializer_config
|
107
140
|
end
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
141
|
+
return @_nested_config[key]
|
142
|
+
end
|
143
|
+
def self.[]=(key, value)
|
144
|
+
unless instance_variable_defined?(:@_nested_config)
|
145
|
+
@_nested_config = self.new.get_serializer_config
|
113
146
|
end
|
147
|
+
return @_nested_config[key] = value
|
114
148
|
end
|
149
|
+
end
|
115
150
|
|
151
|
+
|
152
|
+
# :nocov:
|
153
|
+
# Alias NativeModelSerializer -> NativeSerializer.
|
154
|
+
class RESTFramework::NativeModelSerializer < RESTFramework::NativeSerializer
|
155
|
+
def initialize(**kwargs)
|
156
|
+
super
|
157
|
+
ActiveSupport::Deprecation.warn(
|
158
|
+
<<~MSG.split("\n").join(' ')
|
159
|
+
RESTFramework::NativeModelSerializer is deprecated and will be removed in future versions of
|
160
|
+
REST Framework; you should use RESTFramework::NativeSerializer instead.
|
161
|
+
MSG
|
162
|
+
)
|
163
|
+
end
|
116
164
|
end
|
165
|
+
# :nocov:
|