undercarriage 0.1.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (25) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +42 -4
  3. data/lib/undercarriage.rb +15 -3
  4. data/lib/undercarriage/controllers/action_concern.rb +18 -0
  5. data/lib/undercarriage/controllers/kaminari_concern.rb +11 -0
  6. data/lib/undercarriage/controllers/locale_concern.rb +7 -1
  7. data/lib/undercarriage/controllers/restful/actions/base_concern.rb +120 -0
  8. data/lib/undercarriage/controllers/restful/actions/create_concern.rb +107 -0
  9. data/lib/undercarriage/controllers/restful/actions/destroy_concern.rb +97 -0
  10. data/lib/undercarriage/controllers/restful/actions/edit_concern.rb +94 -0
  11. data/lib/undercarriage/controllers/restful/actions/index_concern.rb +85 -0
  12. data/lib/undercarriage/controllers/restful/actions/new_concern.rb +96 -0
  13. data/lib/undercarriage/controllers/restful/actions/show_concern.rb +91 -0
  14. data/lib/undercarriage/controllers/restful/actions/update_concern.rb +105 -0
  15. data/lib/undercarriage/controllers/restful/flash_concern.rb +112 -0
  16. data/lib/undercarriage/controllers/restful/location_after_concern.rb +79 -0
  17. data/lib/undercarriage/controllers/restful/namespace_concern.rb +41 -0
  18. data/lib/undercarriage/controllers/restful/permitted_attributes_concern.rb +109 -0
  19. data/lib/undercarriage/controllers/restful/utility_concern.rb +74 -0
  20. data/lib/undercarriage/controllers/restful_concern.rb +34 -0
  21. data/lib/undercarriage/models/published_concern.rb +120 -0
  22. data/lib/undercarriage/version.rb +4 -1
  23. metadata +17 -4
  24. data/lib/tasks/undercarriage_tasks.rake +0 -6
  25. data/lib/undercarriage/railtie.rb +0 -6
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Undercarriage
4
+ # :nodoc:
5
+ module Controllers
6
+ # :nodoc:
7
+ module Restful
8
+ # :nodoc:
9
+ module Actions
10
+ ##
11
+ # Update restful action
12
+ #
13
+ # Usage
14
+ # class ExamplesController < ApplicationController
15
+ # include Undercarriage::Controllers::RestfulConcern
16
+ # end
17
+ #
18
+ module UpdateConcern
19
+ extend ActiveSupport::Concern
20
+
21
+ included do
22
+ before_action :update_resource, only: %i[update]
23
+ end
24
+
25
+ ##
26
+ # Update action
27
+ #
28
+ # Usage
29
+ # class ExamplesController < ApplicationController
30
+ # include Undercarriage::Controllers::RestfulConcern
31
+ #
32
+ # ##
33
+ # # This method is only needed if you want to override the action entirely. Otherwise, it is not needed.
34
+ # # Database resources can be accessed as `@update_resource` or `@example`
35
+ # #
36
+ # # def update
37
+ # # ...
38
+ # # end
39
+ # end
40
+ #
41
+ def update
42
+ nested_resource_pre_build
43
+
44
+ if @update_resource.update(update_resource_params)
45
+ after_update_action
46
+
47
+ flash[flash_status_type] = flash_updated_message
48
+
49
+ redirect_to location_after_update
50
+ else
51
+ nested_resource_build
52
+
53
+ render :edit, status: :unprocessable_entity
54
+ end
55
+ end
56
+
57
+ protected
58
+
59
+ ##
60
+ # Update restful action
61
+ #
62
+ # Usage
63
+ # class ExamplesController < ApplicationController
64
+ # include Undercarriage::Controllers::RestfulConcern
65
+ #
66
+ # ##
67
+ # # This method is only needed if you want to override the query entirely. Otherwise, it is not needed.
68
+ # # Database resources can be accessed as `@example`
69
+ # #
70
+ # # def update_resource_content
71
+ # # ...
72
+ # # end
73
+ #
74
+ # ##
75
+ # # To add authorization through something like Pundit, the following could be used
76
+ # #
77
+ # # def update_resource_content
78
+ # # super
79
+ # #
80
+ # # authorize @example
81
+ # # end
82
+ #
83
+ # ##
84
+ # # The `resource_content` method can also be overwritten. Be careful with this because the `show`,
85
+ # # `edit` and `destroy` actions will also use this method
86
+ # #
87
+ # # def resource_content
88
+ # # ...
89
+ # # end
90
+ # end
91
+ #
92
+ def update_resource_content
93
+ resource_content
94
+ end
95
+
96
+ private
97
+
98
+ def update_resource
99
+ @update_resource ||= update_resource_content
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ 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
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Undercarriage
4
+ # :nodoc:
5
+ module Controllers
6
+ # :nodoc:
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
+ #
18
+ module LocationAfterConcern
19
+ extend ActiveSupport::Concern
20
+
21
+ protected
22
+
23
+ ##
24
+ # Location after create
25
+ #
26
+ # The path of the created resource
27
+ #
28
+ def location_after_create
29
+ resource_id = @create_resource
30
+
31
+ resource_path(resource_id)
32
+ end
33
+
34
+ ##
35
+ # Location after update
36
+ #
37
+ # The path of the updated resource
38
+ #
39
+ def location_after_update
40
+ resource_id = @update_resource
41
+
42
+ resource_path(resource_id)
43
+ end
44
+
45
+ ##
46
+ # Location after destroy
47
+ #
48
+ # The path of the resources
49
+ #
50
+ def location_after_destroy
51
+ location_after_save
52
+ end
53
+
54
+ ##
55
+ # Location after save
56
+ #
57
+ # The path of the resources
58
+ #
59
+ def location_after_save
60
+ resources_path
61
+ end
62
+
63
+ private
64
+
65
+ def resource_path(resource, options = {})
66
+ location_path = [resource_namespace, controller_name_singular].compact
67
+
68
+ send("#{location_path.join('_')}_path", resource, options)
69
+ end
70
+
71
+ def resources_path(options = {})
72
+ location_path = [resource_namespace, controller_name].compact
73
+
74
+ polymorphic_path(location_path, options)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Undercarriage
4
+ # :nodoc:
5
+ module Controllers
6
+ # :nodoc:
7
+ module Restful
8
+ ##
9
+ # Namespace
10
+ #
11
+ # Usage
12
+ # class ExamplesController < ApplicationController
13
+ # include Undercarriage::Controllers::Restful::NamespaceConcern
14
+ # end
15
+ #
16
+ module NamespaceConcern
17
+ extend ActiveSupport::Concern
18
+
19
+ protected
20
+
21
+ ##
22
+ # Resource namespace
23
+ #
24
+ # Best guess for namespace. Take `controller_path` and if there is more than one segment, assume the first is
25
+ # the namespace. When there is one segment, the namespace is `nil`
26
+ #
27
+ # Example
28
+ # # Override method that builds namespace
29
+ # def resource_namespace
30
+ # :admin
31
+ # end
32
+ #
33
+ def resource_namespace
34
+ segments = controller_path.split('/')
35
+
36
+ segments.length > 1 ? segments.first : nil
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Undercarriage
4
+ # :nodoc:
5
+ module Controllers
6
+ # :nodoc:
7
+ module Restful
8
+ ##
9
+ # Permitted attributes
10
+ #
11
+ # Usage
12
+ # class ExamplesController < ApplicationController
13
+ # include Undercarriage::Controllers::Restful::PermittedAttributesConcern
14
+ # end
15
+ #
16
+ module PermittedAttributesConcern
17
+ extend ActiveSupport::Concern
18
+
19
+ protected
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
+ #
40
+ def permitted_create_attributes
41
+ permitted_attributes_fallback
42
+ end
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
+ #
63
+ def permitted_update_attributes
64
+ permitted_attributes_fallback
65
+ end
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
+ #
73
+ def resource_new_params
74
+ action_name == 'new' ? nil : create_resource_params
75
+ end
76
+
77
+ ##
78
+ # Permitted params for `create` action
79
+ #
80
+ # Permitted params for the `create` action scoped to the resource.
81
+ #
82
+ def create_resource_params
83
+ permitted = permitted_create_attributes
84
+
85
+ params.require(resource_scope).permit(permitted)
86
+ end
87
+
88
+ ##
89
+ # Permitted params for `update` action
90
+ #
91
+ # Permitted params for the `update` action scoped to the resource.
92
+ #
93
+ def update_resource_params
94
+ permitted = permitted_update_attributes
95
+
96
+ params.require(resource_scope).permit(permitted)
97
+ end
98
+
99
+ private
100
+
101
+ def permitted_attributes_fallback
102
+ with_method = self.class.instance_methods(false).include?(:permitted_attributes)
103
+
104
+ with_method ? permitted_attributes : []
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end