oxidizer 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +103 -0
- data/Rakefile +8 -0
- data/app/assets/config/resourcefully_manifest.js +0 -0
- data/app/controllers/oxidizer/nested_resource_controller.rb +32 -0
- data/app/controllers/oxidizer/nested_resources_controller.rb +91 -0
- data/app/controllers/oxidizer/nested_weak_resource_controller.rb +33 -0
- data/app/controllers/oxidizer/resources_controller.rb +253 -0
- data/config/routes.rb +2 -0
- data/lib/oxidizer/engine.rb +4 -0
- data/lib/oxidizer/version.rb +3 -0
- data/lib/oxidizer.rb +6 -0
- data/lib/tasks/oxidizer_tasks.rake +4 -0
- metadata +74 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ed6b93890738ae60feb4c4d579bb291eda9086fe768b8adb5487a124f7629539
|
4
|
+
data.tar.gz: 46efbd146e216d26325c1fb5024781cce988599b192035a8ad53bb4f00acf508
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cfb69290fbeb108ed02fbabbed97370d3a4fca008a27be406421ba7fb85305896cdb8b22ef926d0ae298d7c6d0eb988e45ba170496ab08a57a936800b066fb75
|
7
|
+
data.tar.gz: 5de271eb48c4ef95ed18e353270d3359b1e12ef1e5c1a0b7a85dce8efe66f16a2b86689a1b6202a1a0fab039f313d11a2c92be30d865ddaf46f3c786db5b16d4
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2022 Brad Gessler
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# Oxidizer
|
2
|
+
|
3
|
+
Rails controllers require a lot of boilerplate for non-trivial Rails applications. Oxidizer resources a lot of the boilerplate and spaghetti code typically seen in Rails controllers by:
|
4
|
+
|
5
|
+
1. Moves authorization out of controller methods and callbacks and into policy objects via Pundit.
|
6
|
+
2. Encourage the use of more, but smaller, controllers to handle various interactions with ActiveRecord objects and other Resources.
|
7
|
+
3. Utiliziers PORO and inheritance for making controller code less verbose, as opposed to a DSL approach, which can be difficult to extend and obscufates how Rails controllers work.
|
8
|
+
4. Encourages keeping business logic out of ActiveRecord objects **and** controllers by utilizing Resource objects.
|
9
|
+
|
10
|
+
Putting that all together, a typical Oxidizer controller that handles CRUD actions for a blog comment feature would look like this:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
# Example Oxidizer controller for comments in a blog post.
|
14
|
+
class CommentsController < Oxidizer::NestedResourcesController
|
15
|
+
protected
|
16
|
+
def self.resource
|
17
|
+
Comment
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parent_resource
|
21
|
+
Post
|
22
|
+
end
|
23
|
+
|
24
|
+
def assign_attributes
|
25
|
+
@comment.user = current_user
|
26
|
+
@comment.blog = @post
|
27
|
+
end
|
28
|
+
|
29
|
+
def permitted_params
|
30
|
+
[:post_id, :body]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
Since there's no DSLs, its easy to extend Oxidizer controllers to implement any type of behavior you need.
|
36
|
+
|
37
|
+
## Installation
|
38
|
+
|
39
|
+
Add to your Rails application Gemfile by executing:
|
40
|
+
|
41
|
+
```bash
|
42
|
+
bundle add "oxidizer"
|
43
|
+
```
|
44
|
+
|
45
|
+
Then run:
|
46
|
+
|
47
|
+
```bash
|
48
|
+
# TODO: Not implemented yet
|
49
|
+
rails generate oxidizer:install
|
50
|
+
```
|
51
|
+
|
52
|
+
This will create the folders and files needed to get going with Oxidizer.
|
53
|
+
|
54
|
+
```txt
|
55
|
+
# TODO: Not implemented yet
|
56
|
+
app/controllers/application_resources_controller.rb
|
57
|
+
```
|
58
|
+
|
59
|
+
## Concepts
|
60
|
+
|
61
|
+
Oxidizer makes it easy to build RESTful Rails applications that follow the CRUD controller pattern and shallow routes.
|
62
|
+
|
63
|
+
## Controller types
|
64
|
+
|
65
|
+
There's a few types of controllers you'll want to use:
|
66
|
+
|
67
|
+
### ResourcesController
|
68
|
+
|
69
|
+
The most common type of controller is a resources controller. Its very much like a vanilla RESTful Rails controller where `index` is the collection of resources and `new`, `create`, `show`, `edit`, `update`, and `destroy` operate on the singular resource.
|
70
|
+
|
71
|
+
For example, a blog web application might have a `Posts` Resources controller.
|
72
|
+
|
73
|
+
### ResourceController
|
74
|
+
|
75
|
+
Similar to above, but does not have an `index` action. Singular resources are commonly used in web applications for managing the current users profile and associated resources.
|
76
|
+
|
77
|
+
For example, a blog web application might have a `Session` Resource controller that the user can create when they login and destroy when they log out.
|
78
|
+
|
79
|
+
### NestedResources
|
80
|
+
|
81
|
+
Nested resources are designed to be scoped within a `Resources`. They have `new`, `create`, and `index` actions, but do not have the remaining actions. The remaining CRUD actions for a nested resource should be `Resources` controller.
|
82
|
+
|
83
|
+
For example, a blog's `Post` resources might have many `Comment` resources per post. The creation of the comment is within the context of the `Post` resource. After the `Comment` resource is created, the `Post` should be persisted in the `Comment` (probably as `comments.post_id`) if it needs to be accessible after its persisted.
|
84
|
+
|
85
|
+
It's possible to have the other CRUD actions in a nested resource, but its discourage since nesting controller scopes can be difficult to maintain as dependencies and business logic change. Best to keep themn flat.
|
86
|
+
|
87
|
+
### NestedResource
|
88
|
+
|
89
|
+
A nested resources is similar to the nested resources, but is singular. For example, a `Post` may have an `Author` resource at `posts/:id/author`. The singular nested resource supports the full range of CRUD actions, but does not have `index`.
|
90
|
+
|
91
|
+
### NestedWeakResource
|
92
|
+
|
93
|
+
A nested weak resource is on where the underlying resource is the same as the parent resource.
|
94
|
+
|
95
|
+
For example, a `Post` may require a confirmation screen before its deleted available at `posts/:id/delete_confirmation/new`. The user would press the `Confirm deletion` button on that screen which would `POST` to `/posts/:id/delete_confirmation` and destroy the object.
|
96
|
+
|
97
|
+
## Contributing
|
98
|
+
|
99
|
+
Open issues with reproducable steps.
|
100
|
+
|
101
|
+
## License
|
102
|
+
|
103
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
File without changes
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Oxidizer
|
2
|
+
# Controller for nesting a singular resource within a parent resource. This
|
3
|
+
# should only be used for creating a new resource within the scope of the parent
|
4
|
+
# resource, or to redirect to the un-nested resource location if it exists.
|
5
|
+
class NestedResourceController < NestedResourcesController
|
6
|
+
def show
|
7
|
+
# Disabled for show because show will only redirect to either
|
8
|
+
# the new resource or to the existing resource, which both have
|
9
|
+
# authorizations of their own. I did this here and not as a `skip_after_filter`
|
10
|
+
# to add safety for a future engineer who might try to incorrectly override
|
11
|
+
# this action and render the resource. If that happened, authorization would
|
12
|
+
# be disabled for them, which wouldn't be great.
|
13
|
+
skip_authorization
|
14
|
+
redirect_to resource.present? ? existing_resource_url : new_resource_url
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
def existing_resource_url
|
19
|
+
url_for resource
|
20
|
+
end
|
21
|
+
|
22
|
+
def new_resource_url
|
23
|
+
url_for action: :new
|
24
|
+
end
|
25
|
+
|
26
|
+
# A single nested resource should only have one resource under
|
27
|
+
# the scope of the parent resources.
|
28
|
+
def find_resource
|
29
|
+
resources.first
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Oxidizer
|
2
|
+
class NestedResourcesController < ResourcesController
|
3
|
+
before_action :assign_parent_resource_instance_variable
|
4
|
+
before_action :assign_resources_instance_variable, only: :index
|
5
|
+
before_action :authorize_parent_resource
|
6
|
+
|
7
|
+
helper_method :parent_resource
|
8
|
+
|
9
|
+
protected
|
10
|
+
def self.parent_resource
|
11
|
+
raise NotImplementedError, "NestedResourcesController.parent_resource must be an ActiveModel or ActiveRecord class"
|
12
|
+
end
|
13
|
+
|
14
|
+
def resources
|
15
|
+
@_resources ||= nested_resource_scope
|
16
|
+
end
|
17
|
+
|
18
|
+
# Use callbacks to share common setup or constraints between actions.
|
19
|
+
def assign_parent_resource_instance_variable
|
20
|
+
instance_variable_set("@#{parent_resource_name}", parent_resource)
|
21
|
+
end
|
22
|
+
|
23
|
+
def parent_resource
|
24
|
+
@_parent_resource ||= find_parent_resource
|
25
|
+
end
|
26
|
+
|
27
|
+
def find_parent_resource
|
28
|
+
self.class.parent_resource.find_resource params[parent_resource_id_param]
|
29
|
+
end
|
30
|
+
|
31
|
+
# Finds the account of the resource depending on the request type and
|
32
|
+
# the parent resource.
|
33
|
+
def find_account
|
34
|
+
if member_request?
|
35
|
+
resource.account
|
36
|
+
elsif parent_resource.is_a? Account
|
37
|
+
parent_resource
|
38
|
+
else
|
39
|
+
parent_resource.account
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# If we're deep, we want to show only members that are scoped
|
44
|
+
# from within an index.
|
45
|
+
def nested_resource_scope
|
46
|
+
query = {}
|
47
|
+
query[parent_resource_foreign_key] = parent_resource
|
48
|
+
resource_scope.where(**query)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Assumes the route key is the foreign key, which is usually the case.
|
52
|
+
# This can be overridden if its not the case or the `nested_resource_scope`
|
53
|
+
# can be over-ridden.
|
54
|
+
def parent_resource_id_param
|
55
|
+
parent_resource_foreign_key
|
56
|
+
end
|
57
|
+
|
58
|
+
# Key used to find the parent resource via ActiveRecord. Typically this is the primary key of the record,
|
59
|
+
# but it would be a different field if you don't want to expose users to primary keys.
|
60
|
+
def parent_active_record_id
|
61
|
+
:id
|
62
|
+
end
|
63
|
+
|
64
|
+
# If the user doesn't have `show?` priviledge on the parent resource,
|
65
|
+
# then its highly likely they won't be authorized to do anything with
|
66
|
+
# the child resource. This isn't 100% true, but I'm having a hard time
|
67
|
+
# thinking of a practical edge case.
|
68
|
+
def authorize_parent_resource
|
69
|
+
authorize parent_resource, :show?
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
def resource_params
|
74
|
+
# Optionally allow the resource params because nested resources usually
|
75
|
+
# allow a POST request with no params that create a resource.
|
76
|
+
if params.key? resource_name
|
77
|
+
params.require(resource_name).permit(permitted_params)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Gets the resource name of the ActiveRecord model for use by
|
82
|
+
# instance methods in this controller.
|
83
|
+
def parent_resource_name
|
84
|
+
self.class.parent_resource.model_name.singular
|
85
|
+
end
|
86
|
+
|
87
|
+
def parent_resource_foreign_key
|
88
|
+
"#{parent_resource_name}_id".to_sym
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Oxidizer
|
2
|
+
# This controller is designed for a "Weak" resource entity, or the `parent_resource`
|
3
|
+
# is the same as the `resource`. This is useful if you want to have complex view logic
|
4
|
+
# in place to change a few parameters on a model.
|
5
|
+
class NestedWeakResourceController < NestedResourcesController
|
6
|
+
def self.resource
|
7
|
+
parent_resource
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
# Prevents callbacks from superclasses from firing that `resources`, not `resource`
|
12
|
+
# routes fire. This is a non-obvios way to keep the inheritance on the simpler side.
|
13
|
+
# TODO: Can I infer a plural vs singular controller in a better way from params? I
|
14
|
+
# could look at action names, but those aren't great. Hmm.
|
15
|
+
def member_request?
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
def find_resource
|
20
|
+
parent_resource
|
21
|
+
end
|
22
|
+
|
23
|
+
# This is for the `account_layout` helper in all sub-classes.
|
24
|
+
def find_account
|
25
|
+
parent_resource.account
|
26
|
+
end
|
27
|
+
|
28
|
+
def assign_new_resource
|
29
|
+
# Do nothing; resource is already created, you're
|
30
|
+
# just doing something to it.
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,253 @@
|
|
1
|
+
module Oxidizer
|
2
|
+
class ResourcesController < ApplicationController
|
3
|
+
before_action :authenticate_user
|
4
|
+
before_action :assign_resource_instance_variable, if: :member_request?
|
5
|
+
before_action :authorize_resource, if: :member_request?
|
6
|
+
before_action :assign_resources_instance_variable, only: :index
|
7
|
+
|
8
|
+
helper_method \
|
9
|
+
:resource_name,
|
10
|
+
:resource_class,
|
11
|
+
:resource,
|
12
|
+
:resources,
|
13
|
+
:created_resource,
|
14
|
+
:updated_resource
|
15
|
+
|
16
|
+
# These are used to contain the serialized IDs for resources so they can
|
17
|
+
# be accessed from views on the other side of the action that's performed.
|
18
|
+
add_flash_types :created_resource, :updated_resource
|
19
|
+
|
20
|
+
def self.resource
|
21
|
+
raise NotImplementedError, "ResourcesController.resource must be an ActiveModel or ActiveRecord class"
|
22
|
+
end
|
23
|
+
|
24
|
+
def index
|
25
|
+
end
|
26
|
+
|
27
|
+
def show
|
28
|
+
end
|
29
|
+
|
30
|
+
def new
|
31
|
+
assign_new_resource
|
32
|
+
assign_attributes
|
33
|
+
authorize_resource
|
34
|
+
end
|
35
|
+
|
36
|
+
def edit
|
37
|
+
end
|
38
|
+
|
39
|
+
def create
|
40
|
+
self.resource = resource_class.new(resource_params)
|
41
|
+
assign_attributes
|
42
|
+
authorize_resource
|
43
|
+
|
44
|
+
respond_to do |format|
|
45
|
+
if resource.save
|
46
|
+
flash_created_resource
|
47
|
+
format.html { redirect_to create_redirect_url, notice: create_notice }
|
48
|
+
format.json { render :show, status: :created, location: resource }
|
49
|
+
create_success_formats format
|
50
|
+
else
|
51
|
+
format.html { render :new, status: :unprocessable_entity }
|
52
|
+
format.json { render json: resource.errors, status: :unprocessable_entity }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def update
|
58
|
+
resource.assign_attributes(resource_params)
|
59
|
+
assign_attributes
|
60
|
+
authorize_resource
|
61
|
+
|
62
|
+
respond_to do |format|
|
63
|
+
if resource.save
|
64
|
+
flash_updated_resource
|
65
|
+
format.html { redirect_to update_redirect_url, notice: update_notice }
|
66
|
+
format.json { render :show, status: :ok, location: resource }
|
67
|
+
else
|
68
|
+
format.html { render :edit, status: :unprocessable_entity }
|
69
|
+
format.json { render json: resource.errors, status: :unprocessable_entity }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def destroy
|
75
|
+
resource.destroy
|
76
|
+
|
77
|
+
respond_to do |format|
|
78
|
+
format.html { redirect_to destroy_redirect_url, notice: destroy_notice }
|
79
|
+
format.json { head :no_content }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
protected
|
84
|
+
def member_request?
|
85
|
+
params.key? resource_id_param
|
86
|
+
end
|
87
|
+
|
88
|
+
def collection_request?
|
89
|
+
!member_request?
|
90
|
+
end
|
91
|
+
|
92
|
+
# Gets the resource name of the ActiveRecord model for use by
|
93
|
+
# instance methods in this controller.
|
94
|
+
def resource_name
|
95
|
+
resource_class.model_name.singular
|
96
|
+
end
|
97
|
+
|
98
|
+
def resources_name
|
99
|
+
resource_class.model_name.plural
|
100
|
+
end
|
101
|
+
|
102
|
+
def resource_class
|
103
|
+
self.class.resource
|
104
|
+
end
|
105
|
+
|
106
|
+
# Permitted params the resource controller allows
|
107
|
+
def permitted_params
|
108
|
+
[]
|
109
|
+
end
|
110
|
+
|
111
|
+
# A scope used for collections scoped by Pundit auth.
|
112
|
+
def resource_scope
|
113
|
+
policy_scope.joins(:user)
|
114
|
+
end
|
115
|
+
|
116
|
+
# `policy_scope` is defined by Pundit.
|
117
|
+
def policy_scope(scope = resource_class)
|
118
|
+
super(scope)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Sets instance variable for templates to match the model name. For
|
122
|
+
# example, `Account` model name would set the `@accounts` instance variable
|
123
|
+
# for template access.
|
124
|
+
def assign_resources_instance_variable
|
125
|
+
instance_variable_set("@#{resources_name}", resources)
|
126
|
+
end
|
127
|
+
|
128
|
+
# A hook that allows sub-classes to assign attributes to a model.
|
129
|
+
def assign_attributes
|
130
|
+
resource.user = current_user if resource.respond_to? :user=
|
131
|
+
end
|
132
|
+
|
133
|
+
# Redirect to this url after a resource is created
|
134
|
+
def create_redirect_url
|
135
|
+
resource
|
136
|
+
end
|
137
|
+
|
138
|
+
# Redirect to this url after a resource is updated
|
139
|
+
def update_redirect_url
|
140
|
+
resource
|
141
|
+
end
|
142
|
+
|
143
|
+
# Redirect to this url after a resource is destroyed
|
144
|
+
def destroy_redirect_url
|
145
|
+
resources_name.to_sym
|
146
|
+
end
|
147
|
+
|
148
|
+
# Key rails routing uses to find resource. Rails resources defaults to the `:id` value.
|
149
|
+
def resource_id_param
|
150
|
+
:id
|
151
|
+
end
|
152
|
+
|
153
|
+
# Use callbacks to share common setup or constraints between actions.
|
154
|
+
def assign_resource_instance_variable
|
155
|
+
instance_variable_set("@#{resource_name}", resource)
|
156
|
+
end
|
157
|
+
|
158
|
+
def resource
|
159
|
+
@_resource ||= find_resource
|
160
|
+
end
|
161
|
+
|
162
|
+
# Sometimes we need to set the resource to hack the controller from another method, such as the
|
163
|
+
# case of setting the instance variable to be an instance of a model.
|
164
|
+
def resource=(value)
|
165
|
+
@_resource = value
|
166
|
+
assign_resource_instance_variable
|
167
|
+
end
|
168
|
+
|
169
|
+
# Finds resource, which is called by `assign_resource` to assign it to the right variables.
|
170
|
+
def find_resource
|
171
|
+
resource_class.find_resource params[resource_id_param]
|
172
|
+
end
|
173
|
+
|
174
|
+
# Initializes a model for the `new` action.
|
175
|
+
def assign_new_resource
|
176
|
+
self.resource = resource_class.new
|
177
|
+
end
|
178
|
+
|
179
|
+
def resources
|
180
|
+
@_resources ||= resource_scope
|
181
|
+
end
|
182
|
+
|
183
|
+
# Additional formats can be specified for successful response creations
|
184
|
+
def create_success_formats(format)
|
185
|
+
end
|
186
|
+
|
187
|
+
# Authorizse resource with Pundit.
|
188
|
+
def authorize_resource(*args)
|
189
|
+
authorize resource, *args
|
190
|
+
end
|
191
|
+
|
192
|
+
# `flash[:notice]` message when a resource is successfully created
|
193
|
+
def create_notice
|
194
|
+
"#{notice_resource_name} created"
|
195
|
+
end
|
196
|
+
|
197
|
+
# `flash[:notice]` message when a resource is successfully updated
|
198
|
+
def update_notice
|
199
|
+
"#{notice_resource_name} updated"
|
200
|
+
end
|
201
|
+
|
202
|
+
# `flash[:notice]` message when a resource is successfully deleted
|
203
|
+
def destroy_notice
|
204
|
+
"#{notice_resource_name} deleted"
|
205
|
+
end
|
206
|
+
|
207
|
+
# What do you call the things that are created?
|
208
|
+
def notice_resource_name
|
209
|
+
resource_name.humanize.capitalize
|
210
|
+
end
|
211
|
+
|
212
|
+
# Get the current account of the resource, if possible.
|
213
|
+
def find_account
|
214
|
+
resource.account if member_request?
|
215
|
+
end
|
216
|
+
|
217
|
+
private
|
218
|
+
# Never trust parameters from the scary internet, only allow the white list through.
|
219
|
+
def resource_params
|
220
|
+
params.require(resource_name).permit(permitted_params)
|
221
|
+
end
|
222
|
+
|
223
|
+
# Assign global_id to resource that was just created. This is used in subsequent
|
224
|
+
# screens to display a link or information about the resource that was just created.
|
225
|
+
def flash_created_resource
|
226
|
+
flash[:created_resource] = resource_global_uri
|
227
|
+
end
|
228
|
+
|
229
|
+
# Resource that was created from the last action.
|
230
|
+
def created_resource
|
231
|
+
@created_resource ||= GlobalID::Locator.locate flash[:created_resource]
|
232
|
+
end
|
233
|
+
|
234
|
+
# Assign global_id to resource that was just created. This is used in subsequent
|
235
|
+
# screens to display a link or information about the resource that was just created.
|
236
|
+
def flash_updated_resource
|
237
|
+
flash[:updated_resource] = resource_global_uri
|
238
|
+
end
|
239
|
+
|
240
|
+
# Generates a GlobalID object that can be serialized into flash for the next action to
|
241
|
+
# pickup and find the object as an updated or created resource. The reason this check
|
242
|
+
# exists is because some resources are ApplicationModels (NOT Records) and don't have
|
243
|
+
# a way to find via ActiveRecord queries.
|
244
|
+
def resource_global_uri
|
245
|
+
resource.to_global_id.uri if resource.respond_to? :to_global_id
|
246
|
+
end
|
247
|
+
|
248
|
+
# Resource that was updated from the last action.
|
249
|
+
def updated_resource
|
250
|
+
@updated_resource ||= GlobalID::Locator.locate flash[:updated_resource]
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
data/config/routes.rb
ADDED
data/lib/oxidizer.rb
ADDED
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oxidizer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brad Gessler
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-06-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 7.0.3
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 7.0.3
|
27
|
+
description: Rapidly build Rails controllers.
|
28
|
+
email:
|
29
|
+
- bradgessler@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- MIT-LICENSE
|
35
|
+
- README.md
|
36
|
+
- Rakefile
|
37
|
+
- app/assets/config/resourcefully_manifest.js
|
38
|
+
- app/controllers/oxidizer/nested_resource_controller.rb
|
39
|
+
- app/controllers/oxidizer/nested_resources_controller.rb
|
40
|
+
- app/controllers/oxidizer/nested_weak_resource_controller.rb
|
41
|
+
- app/controllers/oxidizer/resources_controller.rb
|
42
|
+
- config/routes.rb
|
43
|
+
- lib/oxidizer.rb
|
44
|
+
- lib/oxidizer/engine.rb
|
45
|
+
- lib/oxidizer/version.rb
|
46
|
+
- lib/tasks/oxidizer_tasks.rake
|
47
|
+
homepage: https://github.com/rocketshipio/oxidizer
|
48
|
+
licenses:
|
49
|
+
- MIT
|
50
|
+
metadata:
|
51
|
+
allowed_push_host: https://rubygems.org
|
52
|
+
homepage_uri: https://github.com/rocketshipio/oxidizer
|
53
|
+
source_code_uri: https://github.com/rocketshipio/oxidizer
|
54
|
+
changelog_uri: https://github.com/rocketshipio/oxidizer
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
requirements: []
|
70
|
+
rubygems_version: 3.2.3
|
71
|
+
signing_key:
|
72
|
+
specification_version: 4
|
73
|
+
summary: Rapidly build Rails controllers.
|
74
|
+
test_files: []
|