rest_framework 0.0.16 → 0.1.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 +2 -1
- data/lib/rest_framework/VERSION_STAMP +1 -1
- data/lib/rest_framework/controller_mixins/base.rb +4 -11
- data/lib/rest_framework/controller_mixins/models.rb +16 -9
- data/lib/rest_framework/paginators.rb +1 -1
- data/lib/rest_framework/routers.rb +84 -41
- data/lib/rest_framework/serializers.rb +20 -29
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46db4e7aa05600caaa4c1f9f645f417b4d3cd9e5bcde7da0b54d3c5fa84e872e
|
4
|
+
data.tar.gz: 95c9d018b687795f80c38b43289f19ffd44eb1b170d883c164b590ab6b1c20d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c376d191ffa5ae9de932dceb8411362a00be789ff9aa3733f038608da890fc5437d981576e3b17d402b857f7966cb15e437d7cbe2c8447191088a9a2249134f
|
7
|
+
data.tar.gz: 72e31acb2e66c6d8d2af2dd7375e7732a93b5e66b1c1fedf4c1d781421422c582958d32c6022305cd9cc2ca9dda51e2c2f6c540b1737e11eb3506501ef91b618
|
data/README.md
CHANGED
@@ -117,4 +117,5 @@ $ rake test
|
|
117
117
|
```
|
118
118
|
|
119
119
|
To interact with the test app, `cd test` and operate it via the normal Rails interfaces. Ensure you
|
120
|
-
run `rake db:schema:load` before running `rails server` or `rails console`.
|
120
|
+
run `rake db:schema:load` before running `rails server` or `rails console`. You can also load the
|
121
|
+
test fixtures with `rake db:fixtures:load`.
|
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
@@ -36,8 +36,6 @@ module RESTFramework
|
|
36
36
|
extra_actions: nil,
|
37
37
|
extra_member_actions: nil,
|
38
38
|
filter_backends: nil,
|
39
|
-
native_serializer_config: nil,
|
40
|
-
native_serializer_action_config: nil,
|
41
39
|
paginator_class: nil,
|
42
40
|
page_size: nil,
|
43
41
|
page_query_param: 'page',
|
@@ -77,17 +75,12 @@ module RESTFramework
|
|
77
75
|
|
78
76
|
# Helper to get filtering backends with a sane default.
|
79
77
|
def get_filter_backends
|
80
|
-
|
81
|
-
return self.class.filter_backends
|
82
|
-
end
|
83
|
-
|
84
|
-
# By default, return nil.
|
85
|
-
return nil
|
78
|
+
return self.class.filter_backends || []
|
86
79
|
end
|
87
80
|
|
88
81
|
# Filter the recordset over all configured filter backends.
|
89
82
|
def get_filtered_data(data)
|
90
|
-
|
83
|
+
self.get_filter_backends.each do |filter_class|
|
91
84
|
filter = filter_class.new(controller: self)
|
92
85
|
data = filter.get_filtered_data(data)
|
93
86
|
end
|
@@ -95,9 +88,9 @@ module RESTFramework
|
|
95
88
|
return data
|
96
89
|
end
|
97
90
|
|
98
|
-
# Helper to get the configured serializer class
|
91
|
+
# Helper to get the configured serializer class.
|
99
92
|
def get_serializer_class
|
100
|
-
return self.class.serializer_class
|
93
|
+
return self.class.serializer_class
|
101
94
|
end
|
102
95
|
|
103
96
|
# Get a native serializer config for the current action.
|
@@ -23,6 +23,10 @@ module RESTFramework
|
|
23
23
|
fields: nil,
|
24
24
|
action_fields: nil,
|
25
25
|
|
26
|
+
# Attributes for the default native serializer.
|
27
|
+
native_serializer_config: nil,
|
28
|
+
native_serializer_action_config: nil,
|
29
|
+
|
26
30
|
# Attributes for default model filtering (and ordering).
|
27
31
|
filterset_fields: nil,
|
28
32
|
ordering_fields: nil,
|
@@ -44,6 +48,11 @@ module RESTFramework
|
|
44
48
|
|
45
49
|
protected
|
46
50
|
|
51
|
+
# Helper to get the configured serializer class, or `NativeModelSerializer` as a default.
|
52
|
+
def get_serializer_class
|
53
|
+
return self.class.serializer_class || RESTFramework::NativeModelSerializer
|
54
|
+
end
|
55
|
+
|
47
56
|
# Get a list of parameters allowed for the current action.
|
48
57
|
def get_allowed_parameters
|
49
58
|
allowed_action_parameters = self.class.allowed_action_parameters || {}
|
@@ -57,11 +66,9 @@ module RESTFramework
|
|
57
66
|
|
58
67
|
# Get the list of filtering backends to use.
|
59
68
|
def get_filter_backends
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
# By default, return the standard model filter backend.
|
64
|
-
return [RESTFramework::ModelFilter, RESTFramework::ModelOrderingFilter]
|
69
|
+
return self.class.filter_backends || [
|
70
|
+
RESTFramework::ModelFilter, RESTFramework::ModelOrderingFilter
|
71
|
+
]
|
65
72
|
end
|
66
73
|
|
67
74
|
# Get a list of fields for the current action.
|
@@ -76,14 +83,14 @@ module RESTFramework
|
|
76
83
|
end
|
77
84
|
|
78
85
|
# Filter the request body for keys in current action's allowed_parameters/fields config.
|
79
|
-
def
|
86
|
+
def get_body_params
|
80
87
|
fields = self.get_allowed_parameters || self.get_fields
|
81
|
-
return @
|
88
|
+
return @get_body_params ||= (request.request_parameters.select { |p|
|
82
89
|
fields.include?(p.to_sym) || fields.include?(p.to_s)
|
83
90
|
})
|
84
91
|
end
|
85
|
-
alias :get_create_params :
|
86
|
-
alias :get_update_params :
|
92
|
+
alias :get_create_params :get_body_params
|
93
|
+
alias :get_update_params :get_body_params
|
87
94
|
|
88
95
|
# Get a record by `id` or return a single record if recordset is filtered down to a single
|
89
96
|
# record.
|
@@ -2,6 +2,41 @@ require 'action_dispatch/routing/mapper'
|
|
2
2
|
|
3
3
|
module ActionDispatch::Routing
|
4
4
|
class Mapper
|
5
|
+
# Helper to take extra_actions hash and convert to a consistent format.
|
6
|
+
protected def _parse_extra_actions(extra_actions)
|
7
|
+
return (extra_actions || {}).map do |k,v|
|
8
|
+
kwargs = {}
|
9
|
+
path = k
|
10
|
+
|
11
|
+
# Convert structure to path/methods/kwargs.
|
12
|
+
if v.is_a?(Hash) # allow kwargs
|
13
|
+
v = v.symbolize_keys
|
14
|
+
|
15
|
+
# Ensure methods is an array.
|
16
|
+
if v[:methods].is_a?(String) || v[:methods].is_a?(Symbol)
|
17
|
+
methods = [v.delete(:methods)]
|
18
|
+
else
|
19
|
+
methods = v.delete(:methods)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Override path if it's provided.
|
23
|
+
if v.key?(:path)
|
24
|
+
path = v.delete(:path)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Pass any further kwargs to the underlying Rails interface.
|
28
|
+
kwargs = kwargs.merge(v)
|
29
|
+
elsif v.is_a?(Symbol) || v.is_a?(String)
|
30
|
+
methods = [v]
|
31
|
+
else
|
32
|
+
methods = v
|
33
|
+
end
|
34
|
+
|
35
|
+
# Return a hash with keys: :path, :methods, :kwargs.
|
36
|
+
{path: path, methods: methods, kwargs: kwargs}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
5
40
|
# Private interface to get the controller class from the name and current scope.
|
6
41
|
protected def _get_controller_class(name, pluralize: true, fallback_reverse_pluralization: true)
|
7
42
|
# get class name
|
@@ -40,16 +75,16 @@ module ActionDispatch::Routing
|
|
40
75
|
# @param default_singular [Boolean] the default plurality of the resource if the plurality is
|
41
76
|
# not otherwise defined by the controller
|
42
77
|
# @param name [Symbol] the resource name, from which path and controller are deduced by default
|
43
|
-
# @param skip_undefined [Boolean] whether we should skip routing undefined actions
|
78
|
+
# @param skip_undefined [Boolean] whether we should skip routing undefined resourceful actions
|
44
79
|
protected def _rest_resources(default_singular, name, skip_undefined: true, **kwargs, &block)
|
45
|
-
controller = kwargs
|
80
|
+
controller = kwargs.delete(:controller) || name
|
46
81
|
if controller.is_a?(Class)
|
47
82
|
controller_class = controller
|
48
83
|
else
|
49
84
|
controller_class = _get_controller_class(controller, pluralize: !default_singular)
|
50
85
|
end
|
51
86
|
|
52
|
-
#
|
87
|
+
# Set controller if it's not explicitly set.
|
53
88
|
kwargs[:controller] = name unless kwargs[:controller]
|
54
89
|
|
55
90
|
# determine plural/singular resource
|
@@ -70,25 +105,20 @@ module ActionDispatch::Routing
|
|
70
105
|
public_send(resource_method, name, except: skip, **kwargs) do
|
71
106
|
if controller_class.respond_to?(:extra_member_actions)
|
72
107
|
member do
|
73
|
-
actions = controller_class.extra_member_actions
|
74
|
-
actions
|
75
|
-
|
76
|
-
|
77
|
-
methods.each do |m|
|
78
|
-
public_send(m, action)
|
108
|
+
actions = self._parse_extra_actions(controller_class.extra_member_actions)
|
109
|
+
actions.each do |action_config|
|
110
|
+
action_config[:methods].each do |m|
|
111
|
+
public_send(m, action_config[:path], **action_config[:kwargs])
|
79
112
|
end
|
80
113
|
end
|
81
114
|
end
|
82
115
|
end
|
83
116
|
|
84
117
|
collection do
|
85
|
-
actions = controller_class.extra_actions
|
86
|
-
actions
|
87
|
-
|
88
|
-
|
89
|
-
methods = [methods] if methods.is_a?(Symbol) || methods.is_a?(String)
|
90
|
-
methods.each do |m|
|
91
|
-
public_send(m, action)
|
118
|
+
actions = self._parse_extra_actions(controller_class.extra_actions)
|
119
|
+
actions.each do |action_config|
|
120
|
+
action_config[:methods].each do |m|
|
121
|
+
public_send(m, action_config[:path], **action_config[:kwargs])
|
92
122
|
end
|
93
123
|
end
|
94
124
|
end
|
@@ -112,42 +142,55 @@ module ActionDispatch::Routing
|
|
112
142
|
end
|
113
143
|
|
114
144
|
# Route a controller without the default resourceful paths.
|
115
|
-
def rest_route(
|
116
|
-
controller = kwargs.delete(:controller) ||
|
117
|
-
|
145
|
+
def rest_route(name=nil, **kwargs, &block)
|
146
|
+
controller = kwargs.delete(:controller) || name
|
147
|
+
if controller.is_a?(Class)
|
148
|
+
controller_class = controller
|
149
|
+
else
|
150
|
+
controller_class = self._get_controller_class(controller, pluralize: false)
|
151
|
+
end
|
118
152
|
|
119
|
-
#
|
120
|
-
|
121
|
-
|
122
|
-
actions
|
123
|
-
actions =
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
153
|
+
# Set controller if it's not explicitly set.
|
154
|
+
kwargs[:controller] = name unless kwargs[:controller]
|
155
|
+
|
156
|
+
# Route actions using the resourceful router, but skip all builtin actions.
|
157
|
+
actions = self._parse_extra_actions(controller_class.extra_actions)
|
158
|
+
public_send(:resource, name, only: [], **kwargs) do
|
159
|
+
actions.each do |action_config|
|
160
|
+
action_config[:methods].each do |m|
|
161
|
+
public_send(m, action_config[:path], **action_config[:kwargs])
|
162
|
+
end
|
163
|
+
yield if block_given?
|
129
164
|
end
|
130
|
-
yield if block_given?
|
131
165
|
end
|
132
166
|
end
|
133
167
|
|
134
168
|
# Route a controller's `#root` to '/' in the current scope/namespace, along with other actions.
|
135
169
|
# @param label [Symbol] the snake_case name of the controller
|
136
|
-
def rest_root(
|
137
|
-
#
|
170
|
+
def rest_root(name=nil, **kwargs, &block)
|
171
|
+
# By default, use RootController#root.
|
138
172
|
root_action = kwargs.delete(:action) || :root
|
139
|
-
controller = kwargs.delete(:controller) ||
|
140
|
-
path = path.to_s
|
173
|
+
controller = kwargs.delete(:controller) || name || :root
|
141
174
|
|
142
|
-
#
|
143
|
-
get
|
175
|
+
# Route the root.
|
176
|
+
get name.to_s, controller: controller, action: root_action
|
144
177
|
|
145
|
-
#
|
178
|
+
# Route any additional actions.
|
146
179
|
controller_class = self._get_controller_class(controller, pluralize: false)
|
147
|
-
(controller_class.extra_actions
|
148
|
-
|
149
|
-
|
150
|
-
|
180
|
+
actions = self._parse_extra_actions(controller_class.extra_actions)
|
181
|
+
actions.each do |action_config|
|
182
|
+
# Add :action unless kwargs defines it.
|
183
|
+
unless action_config[:kwargs].key?(:action)
|
184
|
+
action_config[:kwargs][:action] = action_config[:path]
|
185
|
+
end
|
186
|
+
|
187
|
+
action_config[:methods].each do |m|
|
188
|
+
public_send(
|
189
|
+
m,
|
190
|
+
File.join(name.to_s, action_config[:path].to_s),
|
191
|
+
controller: controller,
|
192
|
+
**action_config[:kwargs],
|
193
|
+
)
|
151
194
|
end
|
152
195
|
yield if block_given?
|
153
196
|
end
|
@@ -8,18 +8,25 @@ module RESTFramework
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
# This serializer uses `.as_json` to serialize objects. Despite the name, `.as_json` is
|
12
|
-
# method which converts objects to Ruby primitives (with the top-level being either
|
13
|
-
# hash).
|
14
|
-
class
|
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
15
|
class_attribute :config
|
16
16
|
class_attribute :singular_config
|
17
17
|
class_attribute :plural_config
|
18
18
|
class_attribute :action_config
|
19
19
|
|
20
|
-
def initialize(many: nil, **kwargs)
|
20
|
+
def initialize(many: nil, model: nil, **kwargs)
|
21
21
|
super(**kwargs)
|
22
|
-
|
22
|
+
|
23
|
+
if many.nil?
|
24
|
+
@many = @object.respond_to?(:count) ? @object.count : nil
|
25
|
+
else
|
26
|
+
@many = many
|
27
|
+
end
|
28
|
+
|
29
|
+
@model = model || (@controller ? @controller.send(:get_model) : nil)
|
23
30
|
end
|
24
31
|
|
25
32
|
# Get controller action, if possible.
|
@@ -58,6 +65,13 @@ module RESTFramework
|
|
58
65
|
return serializer_config
|
59
66
|
end
|
60
67
|
|
68
|
+
# If the config wasn't determined, build a serializer config from model fields.
|
69
|
+
fields = @controller.try(:get_fields) if @controller
|
70
|
+
unless fields.blank?
|
71
|
+
columns, methods = fields.partition { |f| f.to_s.in?(@model.column_names) }
|
72
|
+
return {only: columns, methods: methods}
|
73
|
+
end
|
74
|
+
|
61
75
|
return {}
|
62
76
|
end
|
63
77
|
|
@@ -99,27 +113,4 @@ module RESTFramework
|
|
99
113
|
end
|
100
114
|
end
|
101
115
|
|
102
|
-
# `NativeModelSerializer` is similar to `NativeSerializer` but with some customizations to work
|
103
|
-
# with `ActiveModel`.
|
104
|
-
class NativeModelSerializer < NativeSerializer
|
105
|
-
def initialize(model: nil, **kwargs)
|
106
|
-
super(**kwargs)
|
107
|
-
@model = model || (@controller ? @controller.send(:get_model) : nil)
|
108
|
-
end
|
109
|
-
|
110
|
-
# Get a configuration passable to `as_json` for the object.
|
111
|
-
def get_serializer_config
|
112
|
-
config = super
|
113
|
-
return config unless config.blank?
|
114
|
-
|
115
|
-
# If the config wasn't determined, build a serializer config from model fields.
|
116
|
-
fields = @controller.try(:get_fields) if @controller
|
117
|
-
unless fields.blank?
|
118
|
-
columns, methods = fields.partition { |f| f.to_s.in?(@model.column_names) }
|
119
|
-
return {only: columns, methods: methods}
|
120
|
-
end
|
121
|
-
|
122
|
-
return {}
|
123
|
-
end
|
124
|
-
end
|
125
116
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest_framework
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gregory N. Schmit
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-02-
|
11
|
+
date: 2021-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -48,11 +48,11 @@ files:
|
|
48
48
|
- lib/rest_framework/routers.rb
|
49
49
|
- lib/rest_framework/serializers.rb
|
50
50
|
- lib/rest_framework/version.rb
|
51
|
-
homepage: https://
|
51
|
+
homepage: https://rails-rest-framework.com
|
52
52
|
licenses:
|
53
53
|
- MIT
|
54
54
|
metadata:
|
55
|
-
homepage_uri: https://
|
55
|
+
homepage_uri: https://rails-rest-framework.com
|
56
56
|
source_code_uri: https://github.com/gregschmit/rails-rest-framework
|
57
57
|
post_install_message:
|
58
58
|
rdoc_options: []
|
@@ -70,7 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
70
|
- !ruby/object:Gem::Version
|
71
71
|
version: '0'
|
72
72
|
requirements: []
|
73
|
-
rubygems_version: 3.0.
|
73
|
+
rubygems_version: 3.0.9
|
74
74
|
signing_key:
|
75
75
|
specification_version: 4
|
76
76
|
summary: A framework for DRY RESTful APIs in Ruby on Rails.
|