oxidizer 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 +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: []
|