rest_framework 0.9.7 → 0.9.9
Sign up to get free protection for your applications and to get access to all the features.
- 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
|