rest_framework 0.9.7 → 0.9.9
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/.yardopts +5 -0
- data/README.md +73 -45
- data/VERSION +1 -1
- data/app/views/layouts/rest_framework.html.erb +1 -1
- data/app/views/rest_framework/_head.html.erb +1 -2
- data/app/views/rest_framework/_heading.html.erb +1 -1
- data/app/views/rest_framework/_payloads.html.erb +1 -1
- data/app/views/rest_framework/_request_metadata.html.erb +2 -4
- data/app/views/rest_framework/_routes_and_forms.html.erb +2 -2
- data/lib/rest_framework/errors/base_error.rb +5 -0
- data/lib/rest_framework/errors/nil_passed_to_api_response_error.rb +14 -0
- data/lib/rest_framework/errors/unknown_model_error.rb +18 -0
- data/lib/rest_framework/errors.rb +4 -28
- data/lib/rest_framework/filters/{base.rb → base_filter.rb} +4 -1
- data/lib/rest_framework/filters/{model_ordering.rb → model_ordering_filter.rb} +4 -1
- data/lib/rest_framework/filters/{model_query.rb → model_query_filter.rb} +4 -1
- data/lib/rest_framework/filters/{model_search.rb → model_search_filter.rb} +4 -1
- data/lib/rest_framework/filters/{ransack.rb → ransack_filter.rb} +4 -1
- data/lib/rest_framework/filters.rb +5 -5
- data/lib/rest_framework/{controller_mixins/base.rb → mixins/base_controller_mixin.rb} +4 -5
- data/lib/rest_framework/{controller_mixins/bulk.rb → mixins/bulk_model_controller_mixin.rb} +16 -10
- data/lib/rest_framework/{controller_mixins/models.rb → mixins/model_controller_mixin.rb} +34 -53
- data/lib/rest_framework/mixins.rb +7 -0
- data/lib/rest_framework/paginators/base_paginator.rb +19 -0
- data/lib/rest_framework/paginators/page_number_paginator.rb +84 -0
- data/lib/rest_framework/paginators.rb +3 -84
- data/lib/rest_framework/routers.rb +0 -1
- data/lib/rest_framework/serializers/active_model_serializer_adapter_factory.rb +20 -0
- data/lib/rest_framework/serializers/base_serializer.rb +40 -0
- data/lib/rest_framework/serializers/native_serializer.rb +360 -0
- data/lib/rest_framework/serializers.rb +4 -383
- data/lib/rest_framework.rb +1 -1
- metadata +20 -12
- data/lib/rest_framework/controller_mixins.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b816fbe24e240ce66a74b2a3c18fd0a75a449c878c9a0126e4c14ddbaafe5b8
|
4
|
+
data.tar.gz: 383836204fd789afd4270794e0d7da57e05b8b8e8f537dd19c7fa2bf6ff1e2eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a845ce1b30eab8ad874e432268092e5e9117200a320d9446a3e333a88d202257987767fd6b9bad2b7b0768c52e564e1a0beede15408027c7c48c8b91beffcd4
|
7
|
+
data.tar.gz: a1ae6ccfd603c7759d5db717249790a7b124bc06b39ff3f88eba16527874ec8788e4fdcb149c4e96ca0a6a8dae1ea3361519acfb830e1dfda6bc5ea2b521177b
|
data/README.md
CHANGED
@@ -27,87 +27,122 @@ YARD Docs: [rubydoc.info/gems/rest_framework](https://rubydoc.info/gems/rest_fra
|
|
27
27
|
Add this line to your application's Gemfile:
|
28
28
|
|
29
29
|
```ruby
|
30
|
-
gem
|
30
|
+
gem "rest_framework"
|
31
31
|
```
|
32
32
|
|
33
|
-
And then
|
33
|
+
And then run:
|
34
34
|
|
35
35
|
```shell
|
36
|
-
|
36
|
+
bundle install
|
37
37
|
```
|
38
38
|
|
39
|
-
|
39
|
+
## Quick Usage Tutorial
|
40
40
|
|
41
|
-
|
42
|
-
$ gem install rest_framework
|
43
|
-
```
|
41
|
+
This section provides some simple examples to quickly get you started using the framework.
|
44
42
|
|
45
|
-
|
43
|
+
For the purpose of this example, you'll want to add an `api_controller.rb` to your controllers, as
|
44
|
+
well as a directory for the resources:
|
45
|
+
|
46
|
+
```text
|
47
|
+
controllers/
|
48
|
+
├─ api_controller.rb
|
49
|
+
└─ api/
|
50
|
+
├─ root_controller.rb
|
51
|
+
├─ movies_controller.rb
|
52
|
+
└─ users_controller.rb
|
53
|
+
```
|
46
54
|
|
47
55
|
### Controller Mixins
|
48
56
|
|
49
|
-
|
50
|
-
|
51
|
-
action and a simple interface for routing arbitrary additional actions:
|
57
|
+
The root `ApiController` can include any common behavior you want to share across all your API
|
58
|
+
controllers:
|
52
59
|
|
53
60
|
```ruby
|
54
61
|
class ApiController < ApplicationController
|
55
62
|
include RESTFramework::BaseControllerMixin
|
63
|
+
|
64
|
+
# Setting up a paginator class here makes more sense than defining it on every child controller.
|
65
|
+
self.paginator_class = RESTFramework::PageNumberPaginator
|
66
|
+
|
67
|
+
# The page_size attribute doesn't exist on the `BaseControllerMixin`, but for child controllers
|
68
|
+
# that include the `ModelControllerMixin`, they will inherit this attribute and will not overwrite
|
69
|
+
# it.
|
70
|
+
class_attribute(:page_size, default: 30)
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
A root controller can provide actions that exist on the root of your API. It's best to define a
|
75
|
+
dedicated root controller, rather than using the `ApiController` for this purpose, so that actions
|
76
|
+
don't propagate to child controllers:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
class Api::RootController < ApiController
|
56
80
|
self.extra_actions = {test: :get}
|
57
81
|
|
82
|
+
def root
|
83
|
+
return api_response(
|
84
|
+
{
|
85
|
+
message: "Welcome to the API.",
|
86
|
+
how_to_authenticate: <<~END.lines.map(&:strip).join(" "),
|
87
|
+
You can use this API with your normal login session. Otherwise, you can insert your API
|
88
|
+
key into a Bearer Authorization header, or into the URL parameters with the name
|
89
|
+
`api_key`.
|
90
|
+
END
|
91
|
+
},
|
92
|
+
)
|
93
|
+
end
|
94
|
+
|
58
95
|
def test
|
59
|
-
|
96
|
+
return api_response({message: "Hello, world!"})
|
60
97
|
end
|
61
98
|
end
|
62
99
|
```
|
63
100
|
|
64
|
-
|
101
|
+
And here is an example of a resource controller:
|
65
102
|
|
66
103
|
```ruby
|
67
104
|
class Api::MoviesController < ApiController
|
68
105
|
include RESTFramework::ModelControllerMixin
|
69
106
|
|
70
|
-
self.
|
107
|
+
self.fields = [:id, :name, :release_date, :enabled]
|
108
|
+
self.extra_member_actions = {first: :get}
|
109
|
+
|
110
|
+
def first
|
111
|
+
# Always use the bang method, since the framework will rescue `RecordNotFound` and return a
|
112
|
+
# sensible error response.
|
113
|
+
return api_response(self.get_records.first!)
|
114
|
+
end
|
115
|
+
|
116
|
+
def get_recordset
|
117
|
+
return Movie.where(enabled: true)
|
118
|
+
end
|
71
119
|
end
|
72
120
|
```
|
73
121
|
|
74
|
-
|
75
|
-
controller in a way that doesn't make the model obvious, we can set that explicitly:
|
122
|
+
You can also configure a resource's fields dynamically using `include` and `exclude` keys:
|
76
123
|
|
77
124
|
```ruby
|
78
|
-
class Api::
|
79
|
-
include RESTFramework::
|
125
|
+
class Api::UsersController < ApiController
|
126
|
+
include RESTFramework::ModelControllerMixin
|
80
127
|
|
81
|
-
self.
|
128
|
+
self.fields = {include: [:calculated_popularity], exclude: [:impersonation_token]}
|
82
129
|
end
|
83
130
|
```
|
84
131
|
|
85
|
-
Note that you can also override the `get_recordset` instance method to override the API behavior
|
86
|
-
dynamically per-request.
|
87
|
-
|
88
132
|
### Routing
|
89
133
|
|
90
134
|
You can use Rails' `resource`/`resources` routers to route your API, however if you want
|
91
135
|
`extra_actions` / `extra_member_actions` to be routed automatically, then you can use `rest_route`
|
92
|
-
for non-resourceful controllers, or `rest_resource` / `rest_resources` resourceful routers.
|
93
|
-
|
136
|
+
for non-resourceful controllers, or `rest_resource` / `rest_resources` resourceful routers. To route
|
137
|
+
the root, use `rest_root`.
|
94
138
|
|
95
139
|
```ruby
|
96
140
|
Rails.application.routes.draw do
|
97
|
-
|
98
|
-
|
99
|
-
rest_resources :movies
|
100
|
-
rest_resources :users
|
101
|
-
end
|
102
|
-
end
|
103
|
-
```
|
104
|
-
|
105
|
-
Or if you want the API root to be routed to `Api::RootController#root`:
|
141
|
+
# If you wanted to route actions from the `ApiController`, then you would use this:
|
142
|
+
# rest_root :api # Will find `api_controller` and route the `root` action to '/api'.
|
106
143
|
|
107
|
-
```ruby
|
108
|
-
Rails.application.routes.draw do
|
109
144
|
namespace :api do
|
110
|
-
rest_root #
|
145
|
+
rest_root # Will route `Api::RootController#root` to '/' in this namespace ('/api').
|
111
146
|
rest_resources :movies
|
112
147
|
rest_resources :users
|
113
148
|
end
|
@@ -117,14 +152,7 @@ end
|
|
117
152
|
## Development/Testing
|
118
153
|
|
119
154
|
After you clone the repository, cd'ing into the directory should create a new gemset if you are
|
120
|
-
using RVM. Then run `
|
121
|
-
|
122
|
-
To run the test suite:
|
123
|
-
|
124
|
-
```shell
|
125
|
-
$ rails test
|
126
|
-
```
|
155
|
+
using RVM. Then run `bin/setup` to install the appropriate gems and set things up.
|
127
156
|
|
128
157
|
The top-level `bin/rails` proxies all Rails commands to the test project, so you can operate it via
|
129
|
-
the usual commands.
|
130
|
-
`rails console`.
|
158
|
+
the usual commands (e.g., `rails test`, `rails server` and `rails console`).
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.9
|
@@ -29,7 +29,6 @@
|
|
29
29
|
h1, h2, h3, h4, h5, h6 {
|
30
30
|
color: var(--rrf-red);
|
31
31
|
font-weight: normal;
|
32
|
-
margin-bottom: 0;
|
33
32
|
}
|
34
33
|
html[data-bs-theme="dark"] h1,
|
35
34
|
html[data-bs-theme="dark"] h2,
|
@@ -290,7 +289,7 @@
|
|
290
289
|
|
291
290
|
// Convert plain-text links to anchor tag links.
|
292
291
|
function rrfLinkify(text) {
|
293
|
-
return text.replace(/(https?:\/\/[^\s<>"]+)/g, "<a href=\"$1\"
|
292
|
+
return text.replace(/(https?:\/\/[^\s<>"]+)/g, "<a href=\"$1\">$1</a>")
|
294
293
|
}
|
295
294
|
|
296
295
|
// Replace the document when doing form submission (mainly to support PUT/PATCH/DELETE).
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<div class="row">
|
2
2
|
<div>
|
3
3
|
<%= render partial: "rest_framework/heading/actions" if @route_groups.present? %>
|
4
|
-
<h1
|
4
|
+
<h1 style="margin: 0"><%= @heading_title || @title %></h1>
|
5
5
|
<% if @description.present? %>
|
6
6
|
<br><br><p style="display: inline-block; margin-bottom: 0"><%= @description %></p>
|
7
7
|
<% end %>
|
@@ -17,7 +17,7 @@
|
|
17
17
|
<% end %>
|
18
18
|
</ul>
|
19
19
|
</div>
|
20
|
-
<div class="tab-content
|
20
|
+
<div class="tab-content">
|
21
21
|
<div class="tab-pane fade show active" id="tab-json" role="tabpanel">
|
22
22
|
<% if @json_payload.present? %>
|
23
23
|
<div><pre class="rrf-copy"><code class="language-json"><%=
|
@@ -1,16 +1,14 @@
|
|
1
1
|
<div class="row">
|
2
2
|
<div>
|
3
|
-
<pre><code><%
|
3
|
+
<pre class="mb-2"><code class="language-plaintext"><%
|
4
4
|
concat request.request_method
|
5
5
|
if request.method != request.request_method
|
6
6
|
concat " (via #{request.method})"
|
7
7
|
end
|
8
8
|
concat " #{request.path}"
|
9
9
|
%></code></pre>
|
10
|
-
<pre><code><%
|
10
|
+
<pre><code class="language-plaintext"><%
|
11
11
|
concat "HTTP #{response.status} #{response.message}"
|
12
|
-
concat "\n"
|
13
|
-
concat "Content-Type: #{response.content_type}"
|
14
12
|
%></code></pre>
|
15
13
|
</div>
|
16
14
|
</div>
|
@@ -34,7 +34,7 @@
|
|
34
34
|
<% end %>
|
35
35
|
</ul>
|
36
36
|
</div>
|
37
|
-
<div class="tab-content
|
37
|
+
<div class="tab-content">
|
38
38
|
<div class="tab-pane fade show active" id="tab-routes" role="tabpanel">
|
39
39
|
<%= render partial: "rest_framework/routes_and_forms/routes" %>
|
40
40
|
</div>
|
@@ -49,4 +49,4 @@
|
|
49
49
|
</div>
|
50
50
|
<% end %>
|
51
51
|
</div>
|
52
|
-
</div>
|
52
|
+
</div>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class RESTFramework::Errors::NilPassedToAPIResponseError < RESTFramework::Errors::BaseError
|
2
|
+
def message
|
3
|
+
return <<~MSG.split("\n").join(" ")
|
4
|
+
Payload of `nil` was passed to `api_response`; this is unsupported. If you want a blank
|
5
|
+
response, pass `''` (an empty string) as the payload. If this was the result of a `find_by`
|
6
|
+
(or similar Active Record method) not finding a record, you should use the bang version (e.g.,
|
7
|
+
`find_by!`) to raise `ActiveRecord::RecordNotFound`, which the REST controller will catch and
|
8
|
+
return an appropriate error response.
|
9
|
+
MSG
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Alias for convenience.
|
14
|
+
RESTFramework::NilPassedToAPIResponseError = RESTFramework::Errors::NilPassedToAPIResponseError
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class RESTFramework::Errors::UnknownModelError < RESTFramework::Errors::BaseError
|
2
|
+
def initialize(controller_class)
|
3
|
+
super()
|
4
|
+
@controller_class = controller_class
|
5
|
+
end
|
6
|
+
|
7
|
+
def message
|
8
|
+
return <<~MSG.split("\n").join(" ")
|
9
|
+
The model class for `#{@controller_class}` could not be determined. Any controller that
|
10
|
+
includes `RESTFramework::BaseModelControllerMixin` (directly or indirectly) must either set
|
11
|
+
the `model` attribute on the controller, or the model must be deducible from the controller
|
12
|
+
name (e.g., `UsersController` could resolve to the `User` model).
|
13
|
+
MSG
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Alias for convenience.
|
18
|
+
RESTFramework::UnknownModelError = RESTFramework::Errors::UnknownModelError
|
@@ -1,31 +1,7 @@
|
|
1
|
-
|
2
|
-
class RESTFramework::Error < StandardError
|
1
|
+
module RESTFramework::Errors
|
3
2
|
end
|
4
3
|
|
5
|
-
|
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::UnknownModelError < RESTFramework::Error
|
18
|
-
def initialize(controller_class)
|
19
|
-
super()
|
20
|
-
@controller_class = controller_class
|
21
|
-
end
|
4
|
+
require_relative "errors/base_error"
|
22
5
|
|
23
|
-
|
24
|
-
|
25
|
-
The model class for `#{@controller_class}` could not be determined. Any controller that
|
26
|
-
includes `RESTFramework::BaseModelControllerMixin` (directly or indirectly) must either set
|
27
|
-
the `model` attribute on the controller, or the model must be deducible from the controller
|
28
|
-
name (e.g., `UsersController` could resolve to the `User` model).
|
29
|
-
MSG
|
30
|
-
end
|
31
|
-
end
|
6
|
+
require_relative "errors/nil_passed_to_api_response_error"
|
7
|
+
require_relative "errors/unknown_model_error"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class RESTFramework::BaseFilter
|
1
|
+
class RESTFramework::Filters::BaseFilter
|
2
2
|
def initialize(controller:)
|
3
3
|
@controller = controller
|
4
4
|
end
|
@@ -7,3 +7,6 @@ class RESTFramework::BaseFilter
|
|
7
7
|
raise NotImplementedError
|
8
8
|
end
|
9
9
|
end
|
10
|
+
|
11
|
+
# Alias for convenience.
|
12
|
+
RESTFramework::BaseFilter = RESTFramework::Filters::BaseFilter
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# A filter backend which handles ordering of the recordset.
|
2
|
-
class RESTFramework::ModelOrderingFilter < RESTFramework::BaseFilter
|
2
|
+
class RESTFramework::Filters::ModelOrderingFilter < 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
|
@@ -46,3 +46,6 @@ class RESTFramework::ModelOrderingFilter < RESTFramework::BaseFilter
|
|
46
46
|
return data
|
47
47
|
end
|
48
48
|
end
|
49
|
+
|
50
|
+
# Alias for convenience.
|
51
|
+
RESTFramework::ModelOrderingFilter = RESTFramework::Filters::ModelOrderingFilter
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# A simple filtering backend that supports filtering a recordset based on query parameters.
|
2
|
-
class RESTFramework::ModelQueryFilter < RESTFramework::BaseFilter
|
2
|
+
class RESTFramework::Filters::ModelQueryFilter < RESTFramework::Filters::BaseFilter
|
3
3
|
# Get a list of filterset fields for the current action.
|
4
4
|
def _get_fields
|
5
5
|
# Always return a list of strings; `@controller.get_fields` already does this.
|
@@ -49,3 +49,6 @@ class RESTFramework::ModelQueryFilter < RESTFramework::BaseFilter
|
|
49
49
|
return data
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
# Alias for convenience.
|
54
|
+
RESTFramework::ModelQueryFilter = RESTFramework::Filters::ModelQueryFilter
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Multi-field text searching on models.
|
2
|
-
class RESTFramework::ModelSearchFilter < RESTFramework::BaseFilter
|
2
|
+
class RESTFramework::Filters::ModelSearchFilter < RESTFramework::Filters::BaseFilter
|
3
3
|
# Get a list of search fields for the current action.
|
4
4
|
def _get_fields
|
5
5
|
if search_fields = @controller.search_fields
|
@@ -39,3 +39,6 @@ class RESTFramework::ModelSearchFilter < RESTFramework::BaseFilter
|
|
39
39
|
return data
|
40
40
|
end
|
41
41
|
end
|
42
|
+
|
43
|
+
# Alias for convenience.
|
44
|
+
RESTFramework::ModelSearchFilter = RESTFramework::Filters::ModelSearchFilter
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Adapter for the `ransack` gem.
|
2
|
-
class RESTFramework::RansackFilter < RESTFramework::BaseFilter
|
2
|
+
class RESTFramework::Filters::RansackFilter < RESTFramework::Filters::BaseFilter
|
3
3
|
# Filter data according to the request query parameters.
|
4
4
|
def get_filtered_data(data)
|
5
5
|
q = @controller.request.query_parameters[@controller.ransack_query_param]
|
@@ -23,3 +23,6 @@ class RESTFramework::RansackFilter < RESTFramework::BaseFilter
|
|
23
23
|
return data
|
24
24
|
end
|
25
25
|
end
|
26
|
+
|
27
|
+
# Alias for convenience.
|
28
|
+
RESTFramework::RansackFilter = RESTFramework::Filters::RansackFilter
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module RESTFramework::Filters
|
2
2
|
end
|
3
3
|
|
4
|
-
require_relative "filters/
|
4
|
+
require_relative "filters/base_filter"
|
5
5
|
|
6
|
-
require_relative "filters/
|
7
|
-
require_relative "filters/
|
8
|
-
require_relative "filters/
|
9
|
-
require_relative "filters/
|
6
|
+
require_relative "filters/model_ordering_filter"
|
7
|
+
require_relative "filters/model_query_filter"
|
8
|
+
require_relative "filters/model_search_filter"
|
9
|
+
require_relative "filters/ransack_filter"
|
@@ -1,11 +1,7 @@
|
|
1
|
-
require_relative "../errors"
|
2
|
-
require_relative "../serializers"
|
3
|
-
require_relative "../utils"
|
4
|
-
|
5
1
|
# This module provides the common functionality for any controller mixins, a `root` action, and
|
6
2
|
# the ability to route arbitrary actions with `extra_actions`. This is also where `api_response`
|
7
3
|
# is defined.
|
8
|
-
module RESTFramework::BaseControllerMixin
|
4
|
+
module RESTFramework::Mixins::BaseControllerMixin
|
9
5
|
RRF_BASE_CONFIG = {
|
10
6
|
extra_actions: nil,
|
11
7
|
extra_member_actions: nil,
|
@@ -348,3 +344,6 @@ module RESTFramework::BaseControllerMixin
|
|
348
344
|
return api_response(self.get_options_metadata)
|
349
345
|
end
|
350
346
|
end
|
347
|
+
|
348
|
+
# Alias for convenience.
|
349
|
+
RESTFramework::BaseControllerMixin = RESTFramework::Mixins::BaseControllerMixin
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require_relative "
|
1
|
+
require_relative "model_controller_mixin"
|
2
2
|
|
3
3
|
# Mixin for creating records in bulk. This is unique compared to update/destroy because we overload
|
4
4
|
# the existing `create` action to support bulk creation.
|
5
|
-
module RESTFramework::BulkCreateModelMixin
|
5
|
+
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.
|
@@ -32,7 +32,7 @@ module RESTFramework::BulkCreateModelMixin
|
|
32
32
|
end
|
33
33
|
|
34
34
|
# Mixin for updating records in bulk.
|
35
|
-
module RESTFramework::BulkUpdateModelMixin
|
35
|
+
module RESTFramework::Mixins::BulkUpdateModelMixin
|
36
36
|
def update_all
|
37
37
|
records = self.update_all!
|
38
38
|
serialized_records = self.bulk_serialize(records)
|
@@ -57,7 +57,7 @@ module RESTFramework::BulkUpdateModelMixin
|
|
57
57
|
end
|
58
58
|
|
59
59
|
# Mixin for destroying records in bulk.
|
60
|
-
module RESTFramework::BulkDestroyModelMixin
|
60
|
+
module RESTFramework::Mixins::BulkDestroyModelMixin
|
61
61
|
def destroy_all
|
62
62
|
if params[:_json].is_a?(Array)
|
63
63
|
records = self.destroy_all!
|
@@ -84,14 +84,20 @@ module RESTFramework::BulkDestroyModelMixin
|
|
84
84
|
end
|
85
85
|
|
86
86
|
# Mixin that includes all the CRUD bulk mixins.
|
87
|
-
module RESTFramework::BulkModelControllerMixin
|
88
|
-
include RESTFramework::ModelControllerMixin
|
87
|
+
module RESTFramework::Mixins::BulkModelControllerMixin
|
88
|
+
include RESTFramework::Mixins::ModelControllerMixin
|
89
89
|
|
90
|
-
include RESTFramework::BulkCreateModelMixin
|
91
|
-
include RESTFramework::BulkUpdateModelMixin
|
92
|
-
include RESTFramework::BulkDestroyModelMixin
|
90
|
+
include RESTFramework::Mixins::BulkCreateModelMixin
|
91
|
+
include RESTFramework::Mixins::BulkUpdateModelMixin
|
92
|
+
include RESTFramework::Mixins::BulkDestroyModelMixin
|
93
93
|
|
94
94
|
def self.included(base)
|
95
|
-
RESTFramework::ModelControllerMixin.included(base)
|
95
|
+
RESTFramework::Mixins::ModelControllerMixin.included(base)
|
96
96
|
end
|
97
97
|
end
|
98
|
+
|
99
|
+
# Aliases for convenience.
|
100
|
+
RESTFramework::BulkCreateModelMixin = RESTFramework::Mixins::BulkCreateModelMixin
|
101
|
+
RESTFramework::BulkUpdateModelMixin = RESTFramework::Mixins::BulkUpdateModelMixin
|
102
|
+
RESTFramework::BulkDestroyModelMixin = RESTFramework::Mixins::BulkDestroyModelMixin
|
103
|
+
RESTFramework::BulkModelControllerMixin = RESTFramework::Mixins::BulkModelControllerMixin
|