undercarriage 0.2.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +59 -5
- data/lib/undercarriage.rb +2 -3
- data/lib/undercarriage/controllers/action_concern.rb +18 -0
- data/lib/undercarriage/controllers/kaminari_concern.rb +11 -0
- data/lib/undercarriage/controllers/locale_concern.rb +7 -1
- data/lib/undercarriage/controllers/restful/actions/base_concern.rb +79 -1
- data/lib/undercarriage/controllers/restful/actions/create_concern.rb +16 -9
- data/lib/undercarriage/controllers/restful/actions/destroy_concern.rb +10 -2
- data/lib/undercarriage/controllers/restful/actions/edit_concern.rb +3 -4
- data/lib/undercarriage/controllers/restful/actions/index_concern.rb +4 -6
- data/lib/undercarriage/controllers/restful/actions/new_concern.rb +3 -4
- data/lib/undercarriage/controllers/restful/actions/show_concern.rb +4 -6
- data/lib/undercarriage/controllers/restful/actions/update_concern.rb +16 -9
- data/lib/undercarriage/controllers/restful/flash_concern.rb +112 -0
- data/lib/undercarriage/controllers/restful/location_after_concern.rb +32 -0
- data/lib/undercarriage/controllers/restful/namespace_concern.rb +10 -0
- data/lib/undercarriage/controllers/restful/permitted_attributes_concern.rb +65 -2
- data/lib/undercarriage/controllers/restful/utility_concern.rb +37 -0
- data/lib/undercarriage/controllers/restful_concern.rb +2 -0
- data/lib/undercarriage/models/published_concern.rb +120 -0
- data/lib/undercarriage/version.rb +4 -1
- metadata +6 -6
- data/lib/tasks/undercarriage_tasks.rake +0 -6
- data/lib/undercarriage/railtie.rb +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a9348f83d9d2e3924e13edfcb27bcea2a7602479195298e5f9e95ce646e8cb2
|
4
|
+
data.tar.gz: 2f6fe5126d7b6d4db2429118dc9343f30c76609766d313937cf26790cf5ad7e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e10bb005e424d5e25984ccbb92d3bf44b53ce0d4d48d220ef3f71ddc7d884f6bd97a803732c69583ea10dc15704a3d7c5dfd8ebb2548a1ade20c013344d3b8e3
|
7
|
+
data.tar.gz: deb15ab41c1b0c027017c363028a4beabed9a0b92741efb418ec3d8592eb2289ac871f70c947140a7afa2e93c38175d84eae17a98c89466d902510a04501b0d6
|
data/README.md
CHANGED
@@ -2,24 +2,28 @@
|
|
2
2
|
|
3
3
|
**\*Undercarriage is currently under development. It is not ready for production use.\***
|
4
4
|
|
5
|
+
[![CircleCI](https://circleci.com/gh/dfreerksen/undercarriage.svg?style=shield)](https://circleci.com/gh/dfreerksen/undercarriage)
|
6
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/d15980a534f8db936469/maintainability)](https://codeclimate.com/github/dfreerksen/undercarriage/maintainability)
|
7
|
+
[![Test Coverage](https://api.codeclimate.com/v1/badges/d15980a534f8db936469/test_coverage)](https://codeclimate.com/github/dfreerksen/undercarriage/test_coverage)
|
8
|
+
|
5
9
|
Undercarriage is a set of concerns to add to your application to trim some of the fat from controllers and models.
|
6
10
|
|
7
11
|
## Requirements
|
8
12
|
|
9
13
|
* Ruby >= 2.5
|
10
|
-
* Rails >= 6.0
|
14
|
+
* Rails >= 6.0
|
11
15
|
|
12
16
|
## Installation
|
13
17
|
|
14
18
|
Add to your application's Gemfile
|
15
19
|
|
16
|
-
```
|
17
|
-
gem 'undercarriage', '~> 0.
|
20
|
+
```
|
21
|
+
gem 'undercarriage', '~> 0.5'
|
18
22
|
```
|
19
23
|
|
20
24
|
Run the bundle command
|
21
25
|
|
22
|
-
```
|
26
|
+
```
|
23
27
|
$ bundle install
|
24
28
|
```
|
25
29
|
|
@@ -31,9 +35,59 @@ TODO
|
|
31
35
|
|
32
36
|
* [ ] Allow a way to set locale instead of relying on browser preferred language in `Undercarriage::Controllers::LocaleConcern`
|
33
37
|
|
38
|
+
## Testing
|
39
|
+
|
40
|
+
Run tests with one of the following
|
41
|
+
|
42
|
+
```
|
43
|
+
$ bundle exec rspec
|
44
|
+
$ bundle exec rspec spec
|
45
|
+
```
|
46
|
+
|
47
|
+
### Appraisal
|
48
|
+
|
49
|
+
Undercarriage uses [Appraisal](https://github.com/thoughtbot/appraisal) to ensure various dependency versions work as expected
|
50
|
+
|
51
|
+
When dependencies change, run
|
52
|
+
|
53
|
+
```
|
54
|
+
$ bundle exec appraisal install
|
55
|
+
```
|
56
|
+
|
57
|
+
To run tests with Appraisal, run
|
58
|
+
|
59
|
+
```
|
60
|
+
$ bundle exec appraisal rspec
|
61
|
+
```
|
62
|
+
|
34
63
|
## Code Analysis
|
35
64
|
|
36
|
-
|
65
|
+
Various tools are used to ensure code is linted and formatted correctly.
|
66
|
+
|
67
|
+
### RuboCop
|
68
|
+
|
69
|
+
[RuboCop](https://github.com/bbatsov/rubocop) is a Ruby static code analyzer.
|
70
|
+
|
71
|
+
```
|
72
|
+
$ rubocop
|
73
|
+
```
|
74
|
+
|
75
|
+
## Documentation
|
76
|
+
|
77
|
+
[Yard](https://github.com/lsegal/yard) is used to generate documentation. [Online documentation is available](http://www.rubydoc.info/github/dfreerksen/undercarriage/master)
|
78
|
+
|
79
|
+
Build the documentation with one of the following
|
80
|
+
|
81
|
+
```
|
82
|
+
$ yard
|
83
|
+
$ yard doc
|
84
|
+
```
|
85
|
+
|
86
|
+
Build the documentation and list all undocumented objects
|
87
|
+
|
88
|
+
```
|
89
|
+
$ yard stats --list-undoc
|
90
|
+
```
|
37
91
|
|
38
92
|
## License
|
39
93
|
|
data/lib/undercarriage.rb
CHANGED
@@ -12,12 +12,12 @@ require 'undercarriage/controllers/restful/actions/create_concern'
|
|
12
12
|
require 'undercarriage/controllers/restful/actions/edit_concern'
|
13
13
|
require 'undercarriage/controllers/restful/actions/update_concern'
|
14
14
|
require 'undercarriage/controllers/restful/actions/destroy_concern'
|
15
|
+
require 'undercarriage/controllers/restful/flash_concern'
|
15
16
|
require 'undercarriage/controllers/restful/location_after_concern'
|
16
17
|
require 'undercarriage/controllers/restful/namespace_concern'
|
17
18
|
require 'undercarriage/controllers/restful/permitted_attributes_concern'
|
18
19
|
require 'undercarriage/controllers/restful/utility_concern'
|
19
|
-
|
20
|
-
require 'undercarriage/railtie'
|
20
|
+
require 'undercarriage/models/published_concern'
|
21
21
|
|
22
22
|
##
|
23
23
|
# Undercarriage
|
@@ -25,5 +25,4 @@ require 'undercarriage/railtie'
|
|
25
25
|
# Undercarriage is a set of concerns to add to your application to trim some of the fat from controllers and models.
|
26
26
|
#
|
27
27
|
module Undercarriage
|
28
|
-
# Your code goes here...
|
29
28
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
5
6
|
##
|
6
7
|
# Action helpers
|
@@ -209,22 +210,39 @@ module Undercarriage
|
|
209
210
|
|
210
211
|
protected
|
211
212
|
|
213
|
+
##
|
214
|
+
# Action symbol
|
215
|
+
#
|
216
|
+
# Take `action_name` (string) and turn it into a symbol
|
217
|
+
#
|
212
218
|
def action
|
213
219
|
action_name.to_sym
|
214
220
|
end
|
215
221
|
|
222
|
+
##
|
223
|
+
# Collection actions
|
224
|
+
#
|
216
225
|
def collection_actions
|
217
226
|
%i[index]
|
218
227
|
end
|
219
228
|
|
229
|
+
##
|
230
|
+
# Member actions
|
231
|
+
#
|
220
232
|
def member_actions
|
221
233
|
%i[edit show update]
|
222
234
|
end
|
223
235
|
|
236
|
+
##
|
237
|
+
# Create actions
|
238
|
+
#
|
224
239
|
def create_actions
|
225
240
|
%i[create new]
|
226
241
|
end
|
227
242
|
|
243
|
+
##
|
244
|
+
# Update actions
|
245
|
+
#
|
228
246
|
def update_actions
|
229
247
|
%i[edit update]
|
230
248
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
5
6
|
##
|
6
7
|
# Kaminari pagination
|
@@ -61,10 +62,20 @@ module Undercarriage
|
|
61
62
|
|
62
63
|
protected
|
63
64
|
|
65
|
+
##
|
66
|
+
# Items per page key
|
67
|
+
#
|
68
|
+
# Query param to be used to identify count to be returned
|
69
|
+
#
|
64
70
|
def per_page_key
|
65
71
|
:per
|
66
72
|
end
|
67
73
|
|
74
|
+
##
|
75
|
+
# Page numberkey
|
76
|
+
#
|
77
|
+
# Query param to be used to identify page offset
|
78
|
+
#
|
68
79
|
def page_num_key
|
69
80
|
Kaminari.config.param_name
|
70
81
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
5
6
|
##
|
6
7
|
# Identify locale for translations
|
@@ -65,6 +66,11 @@ module Undercarriage
|
|
65
66
|
|
66
67
|
protected
|
67
68
|
|
69
|
+
##
|
70
|
+
# Set I18n locale
|
71
|
+
#
|
72
|
+
# Set I18n locale for the request
|
73
|
+
#
|
68
74
|
def identify_locale(&action)
|
69
75
|
I18n.with_locale(first_available_locale, &action)
|
70
76
|
end
|
@@ -75,7 +81,7 @@ module Undercarriage
|
|
75
81
|
preferred_locales = (accepted_languages_header << I18n.default_locale.to_s).uniq
|
76
82
|
available_locales = I18n.available_locales.map(&:to_s)
|
77
83
|
|
78
|
-
preferred_locales
|
84
|
+
(preferred_locales & available_locales).first
|
79
85
|
end
|
80
86
|
|
81
87
|
def accepted_languages_header
|
@@ -1,15 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
6
|
+
# :nodoc:
|
5
7
|
module Restful
|
8
|
+
# :nodoc:
|
6
9
|
module Actions
|
7
10
|
##
|
8
11
|
# Base restful action
|
9
12
|
#
|
10
13
|
# Usage
|
11
14
|
# class ExamplesController < ApplicationController
|
12
|
-
# include Undercarriage::Controllers::
|
15
|
+
# include Undercarriage::Controllers::Restful::Actions::BaseConcern
|
13
16
|
# end
|
14
17
|
#
|
15
18
|
module BaseConcern
|
@@ -17,10 +20,42 @@ module Undercarriage
|
|
17
20
|
|
18
21
|
protected
|
19
22
|
|
23
|
+
##
|
24
|
+
# New content action
|
25
|
+
#
|
26
|
+
# Decide what content to load based on action name
|
27
|
+
#
|
20
28
|
def resource_new_content
|
21
29
|
action_name == 'new' ? new_resource_content : create_resource_content
|
22
30
|
end
|
23
31
|
|
32
|
+
##
|
33
|
+
# Resource action
|
34
|
+
#
|
35
|
+
# Used for `show`, `edit`, `update` and `destroy` actions unless overwritten
|
36
|
+
#
|
37
|
+
# Usage
|
38
|
+
# class ExamplesController < ApplicationController
|
39
|
+
# include Undercarriage::Controllers::RestfulConcern
|
40
|
+
#
|
41
|
+
# ##
|
42
|
+
# # This method is only needed if you want to override the query entirely. Otherwise, it is not needed.
|
43
|
+
# # Database resources can be accessed as `@example`
|
44
|
+
# #
|
45
|
+
# # def resource_content
|
46
|
+
# # ...
|
47
|
+
# # end
|
48
|
+
#
|
49
|
+
# ##
|
50
|
+
# # To add authorization through something like Pundit, the following could be used
|
51
|
+
# #
|
52
|
+
# # def resource_content
|
53
|
+
# # super
|
54
|
+
# #
|
55
|
+
# # authorize @example
|
56
|
+
# # end
|
57
|
+
# end
|
58
|
+
#
|
24
59
|
def resource_content
|
25
60
|
resource_id = params.fetch(:id)
|
26
61
|
resource_query = model_class.find(resource_id)
|
@@ -28,12 +63,55 @@ module Undercarriage
|
|
28
63
|
instance_variable_set("@#{instance_name}", resource_query)
|
29
64
|
end
|
30
65
|
|
66
|
+
##
|
67
|
+
# Build nested association before action
|
68
|
+
#
|
69
|
+
# Called first thing from `new`, `create`, `edit` and `update` actions. Meant to build a basic resource before
|
70
|
+
# the action is evaluated
|
71
|
+
#
|
72
|
+
# Usage
|
73
|
+
# nested_resource_pre_build
|
74
|
+
# @example.build_image if @example.image.blank?
|
75
|
+
# end
|
76
|
+
#
|
31
77
|
def nested_resource_pre_build; end
|
32
78
|
|
79
|
+
##
|
80
|
+
# Build nested association for action
|
81
|
+
#
|
82
|
+
# Similar to `nested_resource_pre_build` but called in different places. For the `new` and `edit` actions, it
|
83
|
+
# is called right after `nested_resource_pre_build`. For the `create` and `update` actions, it is only called
|
84
|
+
# after validation has failed and before the view is rendered.
|
85
|
+
#
|
86
|
+
# Usage
|
87
|
+
# nested_resource_build
|
88
|
+
# @example.build_image if @example.image.blank?
|
89
|
+
# end
|
90
|
+
#
|
33
91
|
def nested_resource_build; end
|
34
92
|
|
93
|
+
##
|
94
|
+
# After create callback
|
95
|
+
#
|
96
|
+
# Callback after `create` action has created the record.
|
97
|
+
#
|
98
|
+
# Usage
|
99
|
+
# after_create_action
|
100
|
+
# ExampleJob.perform_later(@example.id)
|
101
|
+
# end
|
102
|
+
#
|
35
103
|
def after_create_action; end
|
36
104
|
|
105
|
+
##
|
106
|
+
# After update callback
|
107
|
+
#
|
108
|
+
# Callback after `update` action has updated the record.
|
109
|
+
#
|
110
|
+
# Usage
|
111
|
+
# after_update_action
|
112
|
+
# ExampleJob.perform_later(@example.id)
|
113
|
+
# end
|
114
|
+
#
|
37
115
|
def after_update_action; end
|
38
116
|
end
|
39
117
|
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
6
|
+
# :nodoc:
|
5
7
|
module Restful
|
8
|
+
# :nodoc:
|
6
9
|
module Actions
|
7
10
|
##
|
8
11
|
# Create restful action
|
@@ -38,17 +41,21 @@ module Undercarriage
|
|
38
41
|
def create
|
39
42
|
nested_resource_pre_build
|
40
43
|
|
41
|
-
|
42
|
-
|
44
|
+
respond_to do |format|
|
45
|
+
if @create_resource.save
|
46
|
+
after_create_action
|
43
47
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
format.html do
|
49
|
+
flash[flash_status_type] = flash_created_message
|
50
|
+
|
51
|
+
redirect_to location_after_create
|
52
|
+
end
|
53
|
+
format.json { render :show, status: :created, location: location_after_create }
|
54
|
+
else
|
55
|
+
nested_resource_build
|
49
56
|
|
50
|
-
|
51
|
-
format.
|
57
|
+
format.html { render :new, status: :unprocessable_entity }
|
58
|
+
format.json { render json: @create_resource.errors, status: :unprocessable_entity }
|
52
59
|
end
|
53
60
|
end
|
54
61
|
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
6
|
+
# :nodoc:
|
5
7
|
module Restful
|
8
|
+
# :nodoc:
|
6
9
|
module Actions
|
7
10
|
##
|
8
11
|
# Destroy restful action
|
@@ -38,8 +41,13 @@ module Undercarriage
|
|
38
41
|
def destroy
|
39
42
|
@destroy_resource.destroy
|
40
43
|
|
41
|
-
|
42
|
-
format.html
|
44
|
+
respond_to do |format|
|
45
|
+
format.html do
|
46
|
+
flash[flash_status_type] = flash_destroyed_message
|
47
|
+
|
48
|
+
redirect_to location_after_destroy
|
49
|
+
end
|
50
|
+
format.json { head :no_content }
|
43
51
|
end
|
44
52
|
end
|
45
53
|
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
6
|
+
# :nodoc:
|
5
7
|
module Restful
|
8
|
+
# :nodoc:
|
6
9
|
module Actions
|
7
10
|
##
|
8
11
|
# Edit restful action
|
@@ -38,10 +41,6 @@ module Undercarriage
|
|
38
41
|
def edit
|
39
42
|
nested_resource_pre_build
|
40
43
|
nested_resource_build
|
41
|
-
|
42
|
-
respond_with(@edit_resource) do |format|
|
43
|
-
format.html { render layout: !request.xhr? }
|
44
|
-
end
|
45
44
|
end
|
46
45
|
|
47
46
|
protected
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
6
|
+
# :nodoc:
|
5
7
|
module Restful
|
8
|
+
# :nodoc:
|
6
9
|
module Actions
|
7
10
|
##
|
8
11
|
# Index restful action
|
@@ -35,12 +38,7 @@ module Undercarriage
|
|
35
38
|
# # end
|
36
39
|
# end
|
37
40
|
#
|
38
|
-
def index
|
39
|
-
respond_with(@index_resources) do |format|
|
40
|
-
format.html { render layout: !request.xhr? }
|
41
|
-
format.json { render layout: false }
|
42
|
-
end
|
43
|
-
end
|
41
|
+
def index; end
|
44
42
|
|
45
43
|
protected
|
46
44
|
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
6
|
+
# :nodoc:
|
5
7
|
module Restful
|
8
|
+
# :nodoc:
|
6
9
|
module Actions
|
7
10
|
##
|
8
11
|
# New restful action
|
@@ -38,10 +41,6 @@ module Undercarriage
|
|
38
41
|
def new
|
39
42
|
nested_resource_pre_build
|
40
43
|
nested_resource_build
|
41
|
-
|
42
|
-
respond_with(@new_resource) do |format|
|
43
|
-
format.html { render layout: !request.xhr? }
|
44
|
-
end
|
45
44
|
end
|
46
45
|
|
47
46
|
protected
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
6
|
+
# :nodoc:
|
5
7
|
module Restful
|
8
|
+
# :nodoc:
|
6
9
|
module Actions
|
7
10
|
##
|
8
11
|
# Show restful action
|
@@ -35,12 +38,7 @@ module Undercarriage
|
|
35
38
|
# # end
|
36
39
|
# end
|
37
40
|
#
|
38
|
-
def show
|
39
|
-
respond_with(@show_resource) do |format|
|
40
|
-
format.html { render layout: !request.xhr? }
|
41
|
-
format.json { render layout: false }
|
42
|
-
end
|
43
|
-
end
|
41
|
+
def show; end
|
44
42
|
|
45
43
|
protected
|
46
44
|
|
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
6
|
+
# :nodoc:
|
5
7
|
module Restful
|
8
|
+
# :nodoc:
|
6
9
|
module Actions
|
7
10
|
##
|
8
11
|
# Update restful action
|
@@ -38,17 +41,21 @@ module Undercarriage
|
|
38
41
|
def update
|
39
42
|
nested_resource_pre_build
|
40
43
|
|
41
|
-
|
42
|
-
|
44
|
+
respond_to do |format|
|
45
|
+
if @update_resource.update(update_resource_params)
|
46
|
+
after_update_action
|
43
47
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
format.html do
|
49
|
+
flash[flash_status_type] = flash_updated_message
|
50
|
+
|
51
|
+
redirect_to location_after_update
|
52
|
+
end
|
53
|
+
format.json { render :show, status: :ok, location: location_after_update }
|
54
|
+
else
|
55
|
+
nested_resource_build
|
49
56
|
|
50
|
-
|
51
|
-
format.
|
57
|
+
format.html { render :edit }
|
58
|
+
format.json { render json: @post.errors, status: :unprocessable_entity }
|
52
59
|
end
|
53
60
|
end
|
54
61
|
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Undercarriage
|
4
|
+
# :nodoc:
|
5
|
+
module Controllers
|
6
|
+
# :nodoc:
|
7
|
+
module Restful
|
8
|
+
##
|
9
|
+
# Flash
|
10
|
+
#
|
11
|
+
# Flash messages
|
12
|
+
#
|
13
|
+
# Usage
|
14
|
+
# class ExamplesController < ApplicationController
|
15
|
+
# include Undercarriage::Controllers::Restful::FlashConcern
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# # config/locales/flash.en.yml
|
19
|
+
# flash:
|
20
|
+
# actions:
|
21
|
+
# create:
|
22
|
+
# notice: "%{resource_name} was successfully created."
|
23
|
+
# update:
|
24
|
+
# notice: "%{resource_name} was successfully updated."
|
25
|
+
# destroy:
|
26
|
+
# notice: "%{resource_name} was successfully destroyed."
|
27
|
+
# posts:
|
28
|
+
# create:
|
29
|
+
# notice: "Your %{downcase_resource_name} was created."
|
30
|
+
# update:
|
31
|
+
# notice_html: "<strong>Huzzah!</strong> Your %{downcase_resource_name} was updated."
|
32
|
+
# notice: "Huzzah! Your %{downcase_resource_name} was updated." # Not used since `notice_html` is defined
|
33
|
+
# things:
|
34
|
+
# destroy:
|
35
|
+
# notice: "Good riddance. That wasn't needed anyway."
|
36
|
+
#
|
37
|
+
module FlashConcern
|
38
|
+
extend ActiveSupport::Concern
|
39
|
+
|
40
|
+
included do
|
41
|
+
class_attribute :flash_status_type
|
42
|
+
self.flash_status_type = :success
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
##
|
48
|
+
# Flash message for `#create` action
|
49
|
+
#
|
50
|
+
# Translate create flash message
|
51
|
+
#
|
52
|
+
def flash_created_message
|
53
|
+
flash_message_builder(:create, flash_status_type, 'created')
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Flash message for `#update` action
|
58
|
+
#
|
59
|
+
# Translate update flash message
|
60
|
+
#
|
61
|
+
def flash_updated_message
|
62
|
+
flash_message_builder(:update, flash_status_type, 'updated')
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# Flash message for `#destroy` action
|
67
|
+
#
|
68
|
+
# Translate destroy flash message
|
69
|
+
#
|
70
|
+
def flash_destroyed_message
|
71
|
+
flash_message_builder(:destroy, flash_status_type, 'destroyed')
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def flash_message_builder(action, status, past_tense)
|
77
|
+
defaults = flash_message_defaults(controller_name_singular_human, action, status, past_tense)
|
78
|
+
message = defaults.shift
|
79
|
+
|
80
|
+
I18n.t(message, resource_name: controller_name_singular_human,
|
81
|
+
downcase_resource_name: controller_name_singular,
|
82
|
+
default: defaults)
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# Default flash messages
|
87
|
+
#
|
88
|
+
# List of default flash messages. The following is the list
|
89
|
+
#
|
90
|
+
# flash.[NAMESPACE].[CONTROLLER].[ACTION].[STATUS]_html
|
91
|
+
# flash.[NAMESPACE].[CONTROLLER].[ACTION].[STATUS]
|
92
|
+
# flash.[CONTROLLER].[ACTION].[STATUS]_html
|
93
|
+
# flash.[CONTROLLER].[ACTION].[STATUS]
|
94
|
+
# flash.actions.[ACTION].[STATUS]
|
95
|
+
# English default
|
96
|
+
#
|
97
|
+
def flash_message_defaults(resource_name, action, status, past_tense)
|
98
|
+
controller_with_namespace = [resource_namespace, controller_name].compact.join('.')
|
99
|
+
|
100
|
+
[
|
101
|
+
:"flash.#{controller_with_namespace}.#{action}.#{status}_html",
|
102
|
+
:"flash.#{controller_with_namespace}.#{action}.#{status}",
|
103
|
+
:"flash.#{controller_name}.#{action}.#{status}_html",
|
104
|
+
:"flash.#{controller_name}.#{action}.#{status}",
|
105
|
+
:"flash.actions.#{action}.#{status}",
|
106
|
+
"#{resource_name} was successfully #{past_tense}."
|
107
|
+
]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -1,29 +1,61 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
6
|
+
# :nodoc:
|
5
7
|
module Restful
|
8
|
+
##
|
9
|
+
# Location after
|
10
|
+
#
|
11
|
+
# Redirect locations after create, update or destroy
|
12
|
+
#
|
13
|
+
# Usage
|
14
|
+
# class ExamplesController < ApplicationController
|
15
|
+
# include Undercarriage::Controllers::Restful::LocationAfterConcern
|
16
|
+
# end
|
17
|
+
#
|
6
18
|
module LocationAfterConcern
|
7
19
|
extend ActiveSupport::Concern
|
8
20
|
|
9
21
|
protected
|
10
22
|
|
23
|
+
##
|
24
|
+
# Location after create
|
25
|
+
#
|
26
|
+
# The path of the created resource
|
27
|
+
#
|
11
28
|
def location_after_create
|
12
29
|
resource_id = @create_resource
|
13
30
|
|
14
31
|
resource_path(resource_id)
|
15
32
|
end
|
16
33
|
|
34
|
+
##
|
35
|
+
# Location after update
|
36
|
+
#
|
37
|
+
# The path of the updated resource
|
38
|
+
#
|
17
39
|
def location_after_update
|
18
40
|
resource_id = @update_resource
|
19
41
|
|
20
42
|
resource_path(resource_id)
|
21
43
|
end
|
22
44
|
|
45
|
+
##
|
46
|
+
# Location after destroy
|
47
|
+
#
|
48
|
+
# The path of the resources
|
49
|
+
#
|
23
50
|
def location_after_destroy
|
24
51
|
location_after_save
|
25
52
|
end
|
26
53
|
|
54
|
+
##
|
55
|
+
# Location after save
|
56
|
+
#
|
57
|
+
# The path of the resources
|
58
|
+
#
|
27
59
|
def location_after_save
|
28
60
|
resources_path
|
29
61
|
end
|
@@ -1,8 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
6
|
+
# :nodoc:
|
5
7
|
module Restful
|
8
|
+
##
|
9
|
+
# Namespace
|
10
|
+
#
|
11
|
+
# Usage
|
12
|
+
# class ExamplesController < ApplicationController
|
13
|
+
# include Undercarriage::Controllers::Restful::NamespaceConcern
|
14
|
+
# end
|
15
|
+
#
|
6
16
|
module NamespaceConcern
|
7
17
|
extend ActiveSupport::Concern
|
8
18
|
|
@@ -1,31 +1,95 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
6
|
+
# :nodoc:
|
5
7
|
module Restful
|
8
|
+
##
|
9
|
+
# Permitted attributes
|
10
|
+
#
|
11
|
+
# Usage
|
12
|
+
# class ExamplesController < ApplicationController
|
13
|
+
# include Undercarriage::Controllers::Restful::PermittedAttributesConcern
|
14
|
+
# end
|
15
|
+
#
|
6
16
|
module PermittedAttributesConcern
|
7
17
|
extend ActiveSupport::Concern
|
8
18
|
|
9
19
|
protected
|
10
20
|
|
21
|
+
##
|
22
|
+
# Permitted attributes for `create` action
|
23
|
+
#
|
24
|
+
# Permitted attributes for the `create` action. If `create` and `update` do not need to be different, you can
|
25
|
+
# still override the `permitted_attributes` method which would be applied to both `create` and `update`.
|
26
|
+
#
|
27
|
+
# Example
|
28
|
+
# def permitted_create_attributes
|
29
|
+
# %i[thingy dilly whatsit]
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# # Use this method is `create` and `update` do not need different permitted attributes
|
33
|
+
# def permitted_attributes
|
34
|
+
# [
|
35
|
+
# :thingy, :dilly, :whatsit,
|
36
|
+
# { whosits_attributes: %i[id _destroy name] }
|
37
|
+
# ]
|
38
|
+
# end
|
39
|
+
#
|
11
40
|
def permitted_create_attributes
|
12
41
|
permitted_attributes_fallback
|
13
42
|
end
|
14
43
|
|
44
|
+
##
|
45
|
+
# Permitted attributes for `update` action
|
46
|
+
#
|
47
|
+
# Permitted attributes for the `update` action. If `create` and `update` do not need to be different, you can
|
48
|
+
# still override the `permitted_attributes` method which would be applied to both `create` and `update`.
|
49
|
+
#
|
50
|
+
# Example
|
51
|
+
# def permitted_update_attributes
|
52
|
+
# %i[thingy dilly whatsit]
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# # Use this method is `create` and `update` do not need different permitted attributes
|
56
|
+
# def permitted_attributes
|
57
|
+
# [
|
58
|
+
# :thingy, :dilly, :whatsit,
|
59
|
+
# { whosits_attributes: %i[id _destroy name] }
|
60
|
+
# ]
|
61
|
+
# end
|
62
|
+
#
|
15
63
|
def permitted_update_attributes
|
16
64
|
permitted_attributes_fallback
|
17
65
|
end
|
18
66
|
|
67
|
+
##
|
68
|
+
# New resource decider
|
69
|
+
#
|
70
|
+
# For the `new` action, resource params are `nil`. For the `create` action, resource params are the posted
|
71
|
+
# params from `create_resource_params` method
|
72
|
+
#
|
19
73
|
def resource_new_params
|
20
74
|
action_name == 'new' ? nil : create_resource_params
|
21
75
|
end
|
22
76
|
|
77
|
+
##
|
78
|
+
# Permitted params for `create` action
|
79
|
+
#
|
80
|
+
# Permitted params for the `create` action scoped to the resource.
|
81
|
+
#
|
23
82
|
def create_resource_params
|
24
83
|
permitted = permitted_create_attributes
|
25
84
|
|
26
85
|
params.require(resource_scope).permit(permitted)
|
27
86
|
end
|
28
87
|
|
88
|
+
##
|
89
|
+
# Permitted params for `update` action
|
90
|
+
#
|
91
|
+
# Permitted params for the `update` action scoped to the resource.
|
92
|
+
#
|
29
93
|
def update_resource_params
|
30
94
|
permitted = permitted_update_attributes
|
31
95
|
|
@@ -35,8 +99,7 @@ module Undercarriage
|
|
35
99
|
private
|
36
100
|
|
37
101
|
def permitted_attributes_fallback
|
38
|
-
with_method = self.class.instance_methods(false)
|
39
|
-
.include?(:permitted_attributes)
|
102
|
+
with_method = self.class.instance_methods(false).include?(:permitted_attributes)
|
40
103
|
|
41
104
|
with_method ? permitted_attributes : []
|
42
105
|
end
|
@@ -1,33 +1,70 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
6
|
+
# :nodoc:
|
5
7
|
module Restful
|
8
|
+
##
|
9
|
+
# Utility
|
10
|
+
#
|
11
|
+
# Utility helper methods
|
12
|
+
#
|
13
|
+
# Usage
|
14
|
+
# class ExamplesController < ApplicationController
|
15
|
+
# include Undercarriage::Controllers::Restful::UtilityConcern
|
16
|
+
# end
|
17
|
+
#
|
6
18
|
module UtilityConcern
|
7
19
|
extend ActiveSupport::Concern
|
8
20
|
|
9
21
|
protected
|
10
22
|
|
23
|
+
##
|
24
|
+
# Singular controller name
|
25
|
+
#
|
11
26
|
def controller_name_singular
|
12
27
|
controller_name.to_s.singularize
|
13
28
|
end
|
14
29
|
|
30
|
+
##
|
31
|
+
# Singular human name
|
32
|
+
#
|
33
|
+
def controller_name_singular_human
|
34
|
+
controller_name_singular.humanize
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Model name
|
39
|
+
#
|
15
40
|
def model_name
|
16
41
|
controller_name_singular
|
17
42
|
end
|
18
43
|
|
44
|
+
##
|
45
|
+
# Model class
|
46
|
+
#
|
19
47
|
def model_class
|
20
48
|
model_name.classify.constantize
|
21
49
|
end
|
22
50
|
|
51
|
+
##
|
52
|
+
# Instances name
|
53
|
+
#
|
23
54
|
def instances_name
|
24
55
|
controller_name.to_s
|
25
56
|
end
|
26
57
|
|
58
|
+
##
|
59
|
+
# Instance name
|
60
|
+
#
|
27
61
|
def instance_name
|
28
62
|
model_name
|
29
63
|
end
|
30
64
|
|
65
|
+
##
|
66
|
+
# Resource scope
|
67
|
+
#
|
31
68
|
def resource_scope
|
32
69
|
model_name.to_sym
|
33
70
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Undercarriage
|
4
|
+
# :nodoc:
|
4
5
|
module Controllers
|
5
6
|
##
|
6
7
|
# Restful actions
|
@@ -14,6 +15,7 @@ module Undercarriage
|
|
14
15
|
extend ActiveSupport::Concern
|
15
16
|
|
16
17
|
included do
|
18
|
+
include Undercarriage::Controllers::Restful::FlashConcern
|
17
19
|
include Undercarriage::Controllers::Restful::LocationAfterConcern
|
18
20
|
include Undercarriage::Controllers::Restful::NamespaceConcern
|
19
21
|
include Undercarriage::Controllers::Restful::PermittedAttributesConcern
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Undercarriage
|
4
|
+
# :nodoc:
|
5
|
+
module Models
|
6
|
+
##
|
7
|
+
# Published
|
8
|
+
#
|
9
|
+
# Based on the presence of a datetime in the `published_at` column (configurable) in the database. If there is a
|
10
|
+
# datetime in the column, it is considered published. You need to do your own validation to ensure the value is a
|
11
|
+
# datetime value
|
12
|
+
#
|
13
|
+
# Usage
|
14
|
+
# # Model
|
15
|
+
# class Example < ApplicationRecord
|
16
|
+
# include Undercarriage::Models::PublishedConcern
|
17
|
+
#
|
18
|
+
# ##
|
19
|
+
# # The name of the column is expected to be `published_at`. If that is not the case for you, uncomment the
|
20
|
+
# # following to change the column name
|
21
|
+
# #
|
22
|
+
# # self.published_column = :ready_at
|
23
|
+
#
|
24
|
+
# ##
|
25
|
+
# # The following are useful helpers for the model. They are not part of the concern
|
26
|
+
# #
|
27
|
+
# scope :available, -> { published.where("#{published_column} <= ?", Time.current) }
|
28
|
+
#
|
29
|
+
# def available?
|
30
|
+
# published? && self[published_column] <= Time.current
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# scope :scheduled, -> { published.where("#{published_column} > ?", , Time.current) }
|
34
|
+
#
|
35
|
+
# def scheduled?
|
36
|
+
# published? && self[published_column] > Time.current
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# # Controller
|
41
|
+
# class PagesController < AdminController
|
42
|
+
# def index
|
43
|
+
# @examples = Example.published
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# # View
|
48
|
+
# <% @examples.each do |example| %>
|
49
|
+
# Published?: <%= example.published? %>
|
50
|
+
# <% end %>
|
51
|
+
#
|
52
|
+
module PublishedConcern
|
53
|
+
extend ActiveSupport::Concern
|
54
|
+
|
55
|
+
included do
|
56
|
+
class_attribute :published_column
|
57
|
+
self.published_column = :published_at
|
58
|
+
|
59
|
+
##
|
60
|
+
# Published scope
|
61
|
+
#
|
62
|
+
# Retrieve only published resources
|
63
|
+
#
|
64
|
+
# Usage
|
65
|
+
# class PagesController < AdminController
|
66
|
+
# def index
|
67
|
+
# @examples = Example.published
|
68
|
+
# end
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
scope :published, -> { where.not(published_column => nil) }
|
72
|
+
|
73
|
+
##
|
74
|
+
# Unpublished scope
|
75
|
+
#
|
76
|
+
# Retrieve only unpublished resources
|
77
|
+
#
|
78
|
+
# Usage
|
79
|
+
# class PagesController < AdminController
|
80
|
+
# def index
|
81
|
+
# @examples = Example.unpublished
|
82
|
+
# end
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
scope :unpublished, -> { where(published_column => nil) }
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# Published check
|
90
|
+
#
|
91
|
+
# Check if an item is published based on the presence of a value in the published column. This does not take into
|
92
|
+
# account whether the item is not currently available (scheduled). See module documentation for more information
|
93
|
+
#
|
94
|
+
# Usage
|
95
|
+
# @example.published? => true
|
96
|
+
# @example.published? => false
|
97
|
+
#
|
98
|
+
# @return [Boolean] if resource is published
|
99
|
+
#
|
100
|
+
def published?
|
101
|
+
self[self.class.published_column].present?
|
102
|
+
end
|
103
|
+
|
104
|
+
##
|
105
|
+
# Unpublished check
|
106
|
+
#
|
107
|
+
# Check if an item is unpublished based on the lack of presence of a value in the published column
|
108
|
+
#
|
109
|
+
# Usage
|
110
|
+
# @example.unpublished? => true
|
111
|
+
# @example.unpublished? => false
|
112
|
+
#
|
113
|
+
# @return [Boolean] if resource is unpublished
|
114
|
+
#
|
115
|
+
def unpublished?
|
116
|
+
!published?
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: undercarriage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Freerksen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-03-
|
11
|
+
date: 2021-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 6.0
|
19
|
+
version: '6.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 6.0
|
26
|
+
version: '6.0'
|
27
27
|
description: Undercarriage is a set of concerns to add to your application to trim
|
28
28
|
some of the fat from controllers and models.
|
29
29
|
email:
|
@@ -35,7 +35,6 @@ files:
|
|
35
35
|
- MIT-LICENSE
|
36
36
|
- README.md
|
37
37
|
- Rakefile
|
38
|
-
- lib/tasks/undercarriage_tasks.rake
|
39
38
|
- lib/undercarriage.rb
|
40
39
|
- lib/undercarriage/controllers/action_concern.rb
|
41
40
|
- lib/undercarriage/controllers/kaminari_concern.rb
|
@@ -48,12 +47,13 @@ files:
|
|
48
47
|
- lib/undercarriage/controllers/restful/actions/new_concern.rb
|
49
48
|
- lib/undercarriage/controllers/restful/actions/show_concern.rb
|
50
49
|
- lib/undercarriage/controllers/restful/actions/update_concern.rb
|
50
|
+
- lib/undercarriage/controllers/restful/flash_concern.rb
|
51
51
|
- lib/undercarriage/controllers/restful/location_after_concern.rb
|
52
52
|
- lib/undercarriage/controllers/restful/namespace_concern.rb
|
53
53
|
- lib/undercarriage/controllers/restful/permitted_attributes_concern.rb
|
54
54
|
- lib/undercarriage/controllers/restful/utility_concern.rb
|
55
55
|
- lib/undercarriage/controllers/restful_concern.rb
|
56
|
-
- lib/undercarriage/
|
56
|
+
- lib/undercarriage/models/published_concern.rb
|
57
57
|
- lib/undercarriage/version.rb
|
58
58
|
homepage: https://github.com/dfreerksen/undercarriage
|
59
59
|
licenses:
|