undercarriage 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +33 -5
- data/lib/undercarriage/controllers/kaminari_concern.rb +18 -4
- data/lib/undercarriage/controllers/restful/actions/base_concern.rb +42 -12
- data/lib/undercarriage/controllers/restful/actions/create_concern.rb +14 -5
- data/lib/undercarriage/controllers/restful/actions/destroy_concern.rb +9 -1
- data/lib/undercarriage/controllers/restful/actions/edit_concern.rb +9 -1
- data/lib/undercarriage/controllers/restful/actions/index_concern.rb +17 -1
- data/lib/undercarriage/controllers/restful/actions/new_concern.rb +14 -5
- data/lib/undercarriage/controllers/restful/actions/show_concern.rb +9 -1
- data/lib/undercarriage/controllers/restful/actions/update_concern.rb +9 -1
- data/lib/undercarriage/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b8d42d984572277bb1282c5fa0306028d91ced6801f88bb7ad36f01c05fcd8e8
|
|
4
|
+
data.tar.gz: f3d7690b1fdbf864395695f4a8651bbce2a907333430df01208edd0503419144
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6ee506e32efb9f323e4f5dcfd8494d00050dc0e20a9d4c09244440c0b7269cc52e5024878a91e24db6da67aa88908840931c0559d0ab7028f1a4cb7e932e61cc
|
|
7
|
+
data.tar.gz: 8577454663eaec4d8b20bd5f06bf36bc2d296cca855113e77b5f9b91c33908354f69aa33645e82ba14c3f45e154790008f4d2c309bf4943814ab5b2d8fd28078
|
data/README.md
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
# Undercarriage
|
|
2
2
|
|
|
3
|
-
**\*Undercarriage is currently under development. It is not ready for production use.\***
|
|
4
|
-
|
|
5
3
|
Undercarriage is a set of concerns to add to your application to trim some of the fat from controllers and models.
|
|
6
4
|
|
|
7
5
|
## Requirements
|
|
8
6
|
|
|
9
|
-
* Ruby >= 3.
|
|
7
|
+
* Ruby >= 3.0
|
|
10
8
|
* Rails >= 6.0
|
|
11
9
|
|
|
12
10
|
## Installation
|
|
@@ -14,7 +12,7 @@ Undercarriage is a set of concerns to add to your application to trim some of th
|
|
|
14
12
|
Add to your application's Gemfile
|
|
15
13
|
|
|
16
14
|
```bash
|
|
17
|
-
gem 'undercarriage', '~> 1.
|
|
15
|
+
gem 'undercarriage', '~> 1.1'
|
|
18
16
|
```
|
|
19
17
|
|
|
20
18
|
Run the bundle command
|
|
@@ -25,7 +23,37 @@ $ bundle install
|
|
|
25
23
|
|
|
26
24
|
## Usage
|
|
27
25
|
|
|
28
|
-
|
|
26
|
+
Include `Undercarriage::Controllers::RestfulConcern` in a controller to get full RESTful `index`/`show`/`new`/`create`/`edit`/`update`/`destroy` actions, driven off the controller's own name/path:
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
class PostsController < ApplicationController
|
|
30
|
+
include Undercarriage::Controllers::RestfulConcern
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def permitted_attributes
|
|
35
|
+
[:title, :body]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This infers `Post` as the model, sets `@posts`/`@post` as appropriate, and wires up flash messages, strong params, and redirects with no further code. Override the `*_content` hooks (e.g. `show_content`, `create_content`) or `after_create_action`/`after_update_action` to customize a single action without redefining it — see the YARD docs on each `Undercarriage::Controllers::Restful::*` concern for the full hook list.
|
|
41
|
+
|
|
42
|
+
The standalone concerns can be included individually where you don't want the full RESTful stack:
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
class ExamplesController < ApplicationController
|
|
46
|
+
include Undercarriage::Controllers::ActionConcern # action?/index_action?/etc. view helpers
|
|
47
|
+
include Undercarriage::Controllers::KaminariConcern # page_num/per_page params for Kaminari
|
|
48
|
+
include Undercarriage::Controllers::LocaleConcern # I18n.locale from HTTP_ACCEPT_LANGUAGE
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
class Example < ApplicationRecord
|
|
52
|
+
include Undercarriage::Models::PublishedConcern # published/unpublished scopes
|
|
53
|
+
end
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
See the YARD documentation linked below for every concern's options and examples.
|
|
29
57
|
|
|
30
58
|
## Testing
|
|
31
59
|
|
|
@@ -28,7 +28,8 @@ module Undercarriage
|
|
|
28
28
|
# Items per page
|
|
29
29
|
#
|
|
30
30
|
# The number of items to return in pagination. Will use the Kaminari config `default_per_page` (typically `25`)
|
|
31
|
-
# for the count and will look for `per` in the URL paramaters to override.
|
|
31
|
+
# for the count and will look for `per` in the URL paramaters to override. The result is clamped between `1`
|
|
32
|
+
# and {#per_page_max} so a caller cannot force an unbounded (or negative/zero) number of records per page.
|
|
32
33
|
#
|
|
33
34
|
# This is asseccible from the View as `per_page`
|
|
34
35
|
#
|
|
@@ -37,14 +38,16 @@ module Undercarriage
|
|
|
37
38
|
# @example Request
|
|
38
39
|
# # GET /examples?per=100 # Return 100 items per page
|
|
39
40
|
# # GET /examples?per=10&page=3 # Return page 3 of items with 10 items per page
|
|
41
|
+
# # GET /examples?per=999999999 # Clamped down to per_page_max
|
|
40
42
|
def per_page
|
|
41
|
-
params.fetch(per_page_key, per_page_default).to_i
|
|
43
|
+
params.fetch(per_page_key, per_page_default).to_i.clamp(1, per_page_max)
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
##
|
|
45
47
|
# Page number
|
|
46
48
|
#
|
|
47
|
-
# Will look for the Kaminari config `param_name` (typically `page`) in the URL paramaters.
|
|
49
|
+
# Will look for the Kaminari config `param_name` (typically `page`) in the URL paramaters. The result is
|
|
50
|
+
# clamped to a minimum of `1` so a caller cannot force a negative or zero page number.
|
|
48
51
|
#
|
|
49
52
|
# This is asseccible from the View as `page_num`
|
|
50
53
|
#
|
|
@@ -54,7 +57,7 @@ module Undercarriage
|
|
|
54
57
|
# # GET /examples?page=5 # Return page 5 of items
|
|
55
58
|
# # GET /examples?per=10&page=3 # Return page 3 of items with 10 items per page
|
|
56
59
|
def page_num
|
|
57
|
-
params.fetch(page_num_key, page_num_default).to_i
|
|
60
|
+
params.fetch(page_num_key, page_num_default).to_i.clamp(1, nil)
|
|
58
61
|
end
|
|
59
62
|
|
|
60
63
|
protected
|
|
@@ -100,6 +103,17 @@ module Undercarriage
|
|
|
100
103
|
def page_num_default
|
|
101
104
|
1
|
|
102
105
|
end
|
|
106
|
+
|
|
107
|
+
##
|
|
108
|
+
# Items per page maximum
|
|
109
|
+
#
|
|
110
|
+
# Upper bound enforced on {#per_page} regardless of what the `per` query param requests. Defaults to the
|
|
111
|
+
# Kaminari config `max_per_page` when set, otherwise `100`. Override to allow a different ceiling.
|
|
112
|
+
#
|
|
113
|
+
# @return [Integer] maximum per page count
|
|
114
|
+
def per_page_max
|
|
115
|
+
Kaminari.config.max_per_page || 100
|
|
116
|
+
end
|
|
103
117
|
end
|
|
104
118
|
end
|
|
105
119
|
end
|
|
@@ -37,16 +37,6 @@ module Undercarriage
|
|
|
37
37
|
model_class
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
##
|
|
41
|
-
# New content action
|
|
42
|
-
#
|
|
43
|
-
# Decide what content to load based on action name
|
|
44
|
-
#
|
|
45
|
-
# @return [Object,Hash]
|
|
46
|
-
def resource_new_content
|
|
47
|
-
action_name == "new" ? new_resource_content : create_resource_content
|
|
48
|
-
end
|
|
49
|
-
|
|
50
40
|
##
|
|
51
41
|
# Resource action
|
|
52
42
|
#
|
|
@@ -72,12 +62,52 @@ module Undercarriage
|
|
|
72
62
|
# #
|
|
73
63
|
# # authorize @example
|
|
74
64
|
# # end
|
|
65
|
+
#
|
|
66
|
+
# ##
|
|
67
|
+
# # To override only a single action's query, override its `*_content` hook instead of `resource_content`
|
|
68
|
+
# # itself. The other actions keep using `resource_content`
|
|
69
|
+
# #
|
|
70
|
+
# # def show_content
|
|
71
|
+
# # super
|
|
72
|
+
# #
|
|
73
|
+
# # authorize @example
|
|
74
|
+
# # end
|
|
75
75
|
# end
|
|
76
76
|
def resource_content
|
|
77
77
|
resource_id = params.fetch(:id)
|
|
78
|
-
|
|
78
|
+
resource_scope.find(resource_id)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
##
|
|
82
|
+
# Resource content for the `destroy` action
|
|
83
|
+
#
|
|
84
|
+
# @return [Object,Hash]
|
|
85
|
+
def destroy_content
|
|
86
|
+
resource_content
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
##
|
|
90
|
+
# Resource content for the `edit` action
|
|
91
|
+
#
|
|
92
|
+
# @return [Object,Hash]
|
|
93
|
+
def edit_content
|
|
94
|
+
resource_content
|
|
95
|
+
end
|
|
79
96
|
|
|
80
|
-
|
|
97
|
+
##
|
|
98
|
+
# Resource content for the `show` action
|
|
99
|
+
#
|
|
100
|
+
# @return [Object,Hash]
|
|
101
|
+
def show_content
|
|
102
|
+
resource_content
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
##
|
|
106
|
+
# Resource content for the `update` action
|
|
107
|
+
#
|
|
108
|
+
# @return [Object,Hash]
|
|
109
|
+
def update_content
|
|
110
|
+
resource_content
|
|
81
111
|
end
|
|
82
112
|
|
|
83
113
|
##
|
|
@@ -62,6 +62,14 @@ module Undercarriage
|
|
|
62
62
|
|
|
63
63
|
protected
|
|
64
64
|
|
|
65
|
+
##
|
|
66
|
+
# Create resource content
|
|
67
|
+
#
|
|
68
|
+
# @return [Object] the built resource
|
|
69
|
+
def create_content
|
|
70
|
+
resource_scope.new(create_resource_params)
|
|
71
|
+
end
|
|
72
|
+
|
|
65
73
|
##
|
|
66
74
|
# Create restful action
|
|
67
75
|
#
|
|
@@ -87,15 +95,16 @@ module Undercarriage
|
|
|
87
95
|
# # end
|
|
88
96
|
#
|
|
89
97
|
# ##
|
|
90
|
-
# #
|
|
91
|
-
# #
|
|
98
|
+
# # To change the underlying build without touching instance variable assignment, override
|
|
99
|
+
# # `create_content` instead. Note this is independent from `new_content` (`create` no longer shares
|
|
100
|
+
# # this method with `new`)
|
|
92
101
|
# #
|
|
93
|
-
# # def
|
|
102
|
+
# # def create_content
|
|
94
103
|
# # ...
|
|
95
104
|
# # end
|
|
96
105
|
# end
|
|
97
106
|
def create_resource_content
|
|
98
|
-
resource_query =
|
|
107
|
+
resource_query = create_content
|
|
99
108
|
|
|
100
109
|
instance_variable_set("@#{instance_name}", resource_query)
|
|
101
110
|
end
|
|
@@ -109,7 +118,7 @@ module Undercarriage
|
|
|
109
118
|
#
|
|
110
119
|
# @return [Object] the built resource
|
|
111
120
|
def create_resource
|
|
112
|
-
@create_resource ||=
|
|
121
|
+
@create_resource ||= create_resource_content
|
|
113
122
|
end
|
|
114
123
|
end
|
|
115
124
|
end
|
|
@@ -84,9 +84,17 @@ module Undercarriage
|
|
|
84
84
|
# # def resource_content
|
|
85
85
|
# # ...
|
|
86
86
|
# # end
|
|
87
|
+
#
|
|
88
|
+
# ##
|
|
89
|
+
# # To change the query for `destroy` only, override `destroy_content` instead. The `show`, `edit` and
|
|
90
|
+
# # `update` actions are unaffected
|
|
91
|
+
# #
|
|
92
|
+
# # def destroy_content
|
|
93
|
+
# # ...
|
|
94
|
+
# # end
|
|
87
95
|
# end
|
|
88
96
|
def destroy_resource_content
|
|
89
|
-
|
|
97
|
+
instance_variable_set("@#{instance_name}", destroy_content)
|
|
90
98
|
end
|
|
91
99
|
|
|
92
100
|
private
|
|
@@ -76,9 +76,17 @@ module Undercarriage
|
|
|
76
76
|
# # def resource_content
|
|
77
77
|
# # ...
|
|
78
78
|
# # end
|
|
79
|
+
#
|
|
80
|
+
# ##
|
|
81
|
+
# # To change the query for `edit` only, override `edit_content` instead. The `show`, `update` and
|
|
82
|
+
# # `destroy` actions are unaffected
|
|
83
|
+
# #
|
|
84
|
+
# # def edit_content
|
|
85
|
+
# # ...
|
|
86
|
+
# # end
|
|
79
87
|
# end
|
|
80
88
|
def edit_resource_content
|
|
81
|
-
|
|
89
|
+
instance_variable_set("@#{instance_name}", edit_content)
|
|
82
90
|
end
|
|
83
91
|
|
|
84
92
|
private
|
|
@@ -42,6 +42,14 @@ module Undercarriage
|
|
|
42
42
|
|
|
43
43
|
protected
|
|
44
44
|
|
|
45
|
+
##
|
|
46
|
+
# Index resource content
|
|
47
|
+
#
|
|
48
|
+
# @return [Object] resource collection scope
|
|
49
|
+
def index_content
|
|
50
|
+
resource_scope.all
|
|
51
|
+
end
|
|
52
|
+
|
|
45
53
|
##
|
|
46
54
|
# Index restful action
|
|
47
55
|
#
|
|
@@ -65,9 +73,17 @@ module Undercarriage
|
|
|
65
73
|
# #
|
|
66
74
|
# # authorize @examples
|
|
67
75
|
# # end
|
|
76
|
+
#
|
|
77
|
+
# ##
|
|
78
|
+
# # To change the underlying query without touching instance variable assignment, override
|
|
79
|
+
# # `index_content` instead
|
|
80
|
+
# #
|
|
81
|
+
# # def index_content
|
|
82
|
+
# # ...
|
|
83
|
+
# # end
|
|
68
84
|
# end
|
|
69
85
|
def resources_content
|
|
70
|
-
resources_query =
|
|
86
|
+
resources_query = index_content
|
|
71
87
|
|
|
72
88
|
instance_variable_set("@#{instances_name}", resources_query)
|
|
73
89
|
end
|
|
@@ -45,6 +45,14 @@ module Undercarriage
|
|
|
45
45
|
|
|
46
46
|
protected
|
|
47
47
|
|
|
48
|
+
##
|
|
49
|
+
# New resource content
|
|
50
|
+
#
|
|
51
|
+
# @return [Object] the built resource
|
|
52
|
+
def new_content
|
|
53
|
+
resource_scope.new
|
|
54
|
+
end
|
|
55
|
+
|
|
48
56
|
##
|
|
49
57
|
# New restful action
|
|
50
58
|
#
|
|
@@ -70,15 +78,16 @@ module Undercarriage
|
|
|
70
78
|
# # end
|
|
71
79
|
#
|
|
72
80
|
# ##
|
|
73
|
-
# #
|
|
74
|
-
# #
|
|
81
|
+
# # To change the underlying build without touching instance variable assignment, override
|
|
82
|
+
# # `new_content` instead. Note this is independent from `create_content` (`create` no longer shares
|
|
83
|
+
# # this method with `new`)
|
|
75
84
|
# #
|
|
76
|
-
# # def
|
|
85
|
+
# # def new_content
|
|
77
86
|
# # ...
|
|
78
87
|
# # end
|
|
79
88
|
# end
|
|
80
89
|
def new_resource_content
|
|
81
|
-
resource_query =
|
|
90
|
+
resource_query = new_content
|
|
82
91
|
|
|
83
92
|
instance_variable_set("@#{instance_name}", resource_query)
|
|
84
93
|
end
|
|
@@ -92,7 +101,7 @@ module Undercarriage
|
|
|
92
101
|
#
|
|
93
102
|
# @return [Object] the built resource
|
|
94
103
|
def new_resource
|
|
95
|
-
@new_resource ||=
|
|
104
|
+
@new_resource ||= new_resource_content
|
|
96
105
|
end
|
|
97
106
|
end
|
|
98
107
|
end
|
|
@@ -73,9 +73,17 @@ module Undercarriage
|
|
|
73
73
|
# # def resource_content
|
|
74
74
|
# # ...
|
|
75
75
|
# # end
|
|
76
|
+
#
|
|
77
|
+
# ##
|
|
78
|
+
# # To change the query for `show` only, override `show_content` instead. The `edit`, `update` and
|
|
79
|
+
# # `destroy` actions are unaffected
|
|
80
|
+
# #
|
|
81
|
+
# # def show_content
|
|
82
|
+
# # ...
|
|
83
|
+
# # end
|
|
76
84
|
# end
|
|
77
85
|
def show_resource_content
|
|
78
|
-
|
|
86
|
+
instance_variable_set("@#{instance_name}", show_content)
|
|
79
87
|
end
|
|
80
88
|
|
|
81
89
|
private
|
|
@@ -93,9 +93,17 @@ module Undercarriage
|
|
|
93
93
|
# # def resource_content
|
|
94
94
|
# # ...
|
|
95
95
|
# # end
|
|
96
|
+
#
|
|
97
|
+
# ##
|
|
98
|
+
# # To change the query for `update` only, override `update_content` instead. The `show`, `edit` and
|
|
99
|
+
# # `destroy` actions are unaffected
|
|
100
|
+
# #
|
|
101
|
+
# # def update_content
|
|
102
|
+
# # ...
|
|
103
|
+
# # end
|
|
96
104
|
# end
|
|
97
105
|
def update_resource_content
|
|
98
|
-
|
|
106
|
+
instance_variable_set("@#{instance_name}", update_content)
|
|
99
107
|
end
|
|
100
108
|
|
|
101
109
|
private
|