undercarriage 0.5.5 → 1.0.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.
@@ -10,30 +10,32 @@ module Undercarriage
10
10
  #
11
11
  # Flash messages
12
12
  #
13
- # Usage
14
- # class ExamplesController < ApplicationController
15
- # include Undercarriage::Controllers::Restful::FlashConcern
16
- # end
13
+ # FlashConcern is not meant to be included alone
17
14
  #
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."
15
+ # I18n - config/locales/flash.en.yml:
36
16
  #
17
+ # flash:
18
+ # actions:
19
+ # create:
20
+ # notice: "%{resource_name} was successfully created."
21
+ # update:
22
+ # notice: "%{resource_name} was successfully updated."
23
+ # destroy:
24
+ # notice: "%{resource_name} was successfully destroyed."
25
+ # posts:
26
+ # create:
27
+ # notice: "Your %{downcase_resource_name} was created."
28
+ # update:
29
+ # notice_html: "<strong>Huzzah!</strong> Your %{downcase_resource_name} was updated."
30
+ # notice: "Huzzah! Your %{downcase_resource_name} was updated."
31
+ # things:
32
+ # destroy:
33
+ # notice: "Good riddance. That wasn't needed anyway."
34
+ #
35
+ # @example Controller
36
+ # class ExamplesController < ApplicationController
37
+ # include Undercarriage::Controllers::RestfulConcern
38
+ # end
37
39
  module FlashConcern
38
40
  extend ActiveSupport::Concern
39
41
 
@@ -49,8 +51,9 @@ module Undercarriage
49
51
  #
50
52
  # Translate create flash message
51
53
  #
54
+ # @return [String] translation
52
55
  def flash_created_message
53
- flash_message_builder(:create, flash_status_type, 'created')
56
+ flash_message_builder(:create, flash_status_type, "created")
54
57
  end
55
58
 
56
59
  ##
@@ -58,8 +61,9 @@ module Undercarriage
58
61
  #
59
62
  # Translate update flash message
60
63
  #
64
+ # @return [String] translation
61
65
  def flash_updated_message
62
- flash_message_builder(:update, flash_status_type, 'updated')
66
+ flash_message_builder(:update, flash_status_type, "updated")
63
67
  end
64
68
 
65
69
  ##
@@ -67,12 +71,23 @@ module Undercarriage
67
71
  #
68
72
  # Translate destroy flash message
69
73
  #
74
+ # @return [String] translation
70
75
  def flash_destroyed_message
71
- flash_message_builder(:destroy, flash_status_type, 'destroyed')
76
+ flash_message_builder(:destroy, flash_status_type, "destroyed")
72
77
  end
73
78
 
74
79
  private
75
80
 
81
+ ##
82
+ # Flash message builder
83
+ #
84
+ # Builds and translates the flash message for the given action, looking up translations through
85
+ # `flash_message_defaults`'s fallback chain.
86
+ #
87
+ # @param action [Symbol] the controller action (`:create`, `:update`, `:destroy`)
88
+ # @param status [Symbol] the flash status type (e.g. `:success`)
89
+ # @param past_tense [String] past-tense verb used in the hardcoded English fallback
90
+ # @return [String] translated flash message
76
91
  def flash_message_builder(action, status, past_tense)
77
92
  defaults = flash_message_defaults(controller_name_singular_title, action, status, past_tense)
78
93
  message = defaults.shift
@@ -91,17 +106,20 @@ module Undercarriage
91
106
  # flash.[NAMESPACE].[CONTROLLER].[ACTION].[STATUS]
92
107
  # flash.[CONTROLLER].[ACTION].[STATUS]_html
93
108
  # flash.[CONTROLLER].[ACTION].[STATUS]
109
+ # flash.actions.[ACTION].[STATUS]_html
94
110
  # flash.actions.[ACTION].[STATUS]
95
111
  # English default
96
112
  #
113
+ # @return [Array] possible translation paths
97
114
  def flash_message_defaults(resource_name, action, status, past_tense)
98
- controller_with_namespace = [resource_namespace, controller_name].compact.join('.')
115
+ controller_with_namespace = [resource_namespace, controller_name].compact.join(".")
99
116
 
100
117
  [
101
118
  :"flash.#{controller_with_namespace}.#{action}.#{status}_html",
102
119
  :"flash.#{controller_with_namespace}.#{action}.#{status}",
103
120
  :"flash.#{controller_name}.#{action}.#{status}_html",
104
121
  :"flash.#{controller_name}.#{action}.#{status}",
122
+ :"flash.actions.#{action}.#{status}_html",
105
123
  :"flash.actions.#{action}.#{status}",
106
124
  "#{resource_name} was successfully #{past_tense}."
107
125
  ]
@@ -10,11 +10,12 @@ module Undercarriage
10
10
  #
11
11
  # Redirect locations after create, update or destroy
12
12
  #
13
- # Usage
13
+ # LocationAfterConcern is not meant to be included alone
14
+ #
15
+ # @example Controller
14
16
  # class ExamplesController < ApplicationController
15
- # include Undercarriage::Controllers::Restful::LocationAfterConcern
17
+ # include Undercarriage::Controllers::RestfulConcern
16
18
  # end
17
- #
18
19
  module LocationAfterConcern
19
20
  extend ActiveSupport::Concern
20
21
 
@@ -25,6 +26,7 @@ module Undercarriage
25
26
  #
26
27
  # The path of the created resource
27
28
  #
29
+ # @return [String] path after create redirect
28
30
  def location_after_create
29
31
  resource_id = @create_resource
30
32
 
@@ -36,6 +38,7 @@ module Undercarriage
36
38
  #
37
39
  # The path of the updated resource
38
40
  #
41
+ # @return [String] path after update redirect
39
42
  def location_after_update
40
43
  resource_id = @update_resource
41
44
 
@@ -47,6 +50,7 @@ module Undercarriage
47
50
  #
48
51
  # The path of the resources
49
52
  #
53
+ # @return [String] path after destroy redirect
50
54
  def location_after_destroy
51
55
  location_after_save
52
56
  end
@@ -56,18 +60,34 @@ module Undercarriage
56
60
  #
57
61
  # The path of the resources
58
62
  #
63
+ # @return [String] generic path after save redirect
59
64
  def location_after_save
60
65
  resources_path
61
66
  end
62
67
 
63
68
  private
64
69
 
70
+ ##
71
+ # Resource path
72
+ #
73
+ # The path for a single resource, honoring any inferred admin/nested namespace.
74
+ #
75
+ # @param resource [Object] resource to build the path for
76
+ # @param options [Hash] additional options forwarded to the path helper
77
+ # @return [String] resource path
65
78
  def resource_path(resource, options = {})
66
79
  location_path = [resource_namespace, controller_name_singular].compact
67
80
 
68
81
  send("#{location_path.join('_')}_path", resource, options)
69
82
  end
70
83
 
84
+ ##
85
+ # Resources path
86
+ #
87
+ # The path for the resource collection, honoring any inferred admin/nested namespace.
88
+ #
89
+ # @param options [Hash] additional options forwarded to `polymorphic_path`
90
+ # @return [String] resources path
71
91
  def resources_path(options = {})
72
92
  location_path = [resource_namespace, controller_name].compact.map(&:to_sym)
73
93
 
@@ -8,11 +8,12 @@ module Undercarriage
8
8
  ##
9
9
  # Namespace
10
10
  #
11
- # Usage
11
+ # NamespaceConcern is not meant to be included alone
12
+ #
13
+ # @example Controller
12
14
  # class ExamplesController < ApplicationController
13
- # include Undercarriage::Controllers::Restful::NamespaceConcern
15
+ # include Undercarriage::Controllers::RestfulConcern
14
16
  # end
15
- #
16
17
  module NamespaceConcern
17
18
  extend ActiveSupport::Concern
18
19
 
@@ -24,14 +25,13 @@ module Undercarriage
24
25
  # Best guess for namespace. Take `controller_path` and if there is more than one segment, assume the first is
25
26
  # the namespace. When there is one segment, the namespace is `nil`
26
27
  #
27
- # Example
28
+ # @example Controller
28
29
  # # Override method that builds namespace
29
30
  # def resource_namespace
30
31
  # :admin
31
32
  # end
32
- #
33
33
  def resource_namespace
34
- segments = controller_path.split('/')
34
+ segments = controller_path.split("/")
35
35
 
36
36
  segments.length > 1 ? segments.first : nil
37
37
  end
@@ -8,11 +8,12 @@ module Undercarriage
8
8
  ##
9
9
  # Permitted attributes
10
10
  #
11
- # Usage
11
+ # PermittedAttributesConcern is not meant to be included alone
12
+ #
13
+ # @example Controller
12
14
  # class ExamplesController < ApplicationController
13
- # include Undercarriage::Controllers::Restful::PermittedAttributesConcern
15
+ # include Undercarriage::Controllers::RestfulConcern
14
16
  # end
15
- #
16
17
  module PermittedAttributesConcern
17
18
  extend ActiveSupport::Concern
18
19
 
@@ -24,7 +25,9 @@ module Undercarriage
24
25
  # Permitted attributes for the `create` action. If `create` and `update` do not need to be different, you can
25
26
  # still override the `permitted_attributes` method which would be applied to both `create` and `update`.
26
27
  #
27
- # Example
28
+ # @return [Array,Hash] permitted create attributes
29
+ #
30
+ # @example Controller
28
31
  # def permitted_create_attributes
29
32
  # %i[thingy dilly whatsit]
30
33
  # end
@@ -36,7 +39,6 @@ module Undercarriage
36
39
  # { whosits_attributes: %i[id _destroy name] }
37
40
  # ]
38
41
  # end
39
- #
40
42
  def permitted_create_attributes
41
43
  permitted_attributes_fallback
42
44
  end
@@ -47,7 +49,9 @@ module Undercarriage
47
49
  # Permitted attributes for the `update` action. If `create` and `update` do not need to be different, you can
48
50
  # still override the `permitted_attributes` method which would be applied to both `create` and `update`.
49
51
  #
50
- # Example
52
+ # @return [Array,Hash] permitted update attributes
53
+ #
54
+ # @example Controller
51
55
  # def permitted_update_attributes
52
56
  # %i[thingy dilly whatsit]
53
57
  # end
@@ -59,7 +63,6 @@ module Undercarriage
59
63
  # { whosits_attributes: %i[id _destroy name] }
60
64
  # ]
61
65
  # end
62
- #
63
66
  def permitted_update_attributes
64
67
  permitted_attributes_fallback
65
68
  end
@@ -70,36 +73,42 @@ module Undercarriage
70
73
  # For the `new` action, resource params are `nil`. For the `create` action, resource params are the posted
71
74
  # params from `create_resource_params` method
72
75
  #
76
+ # @return [Array,Hash,nil] permitted new attributes
73
77
  def resource_new_params
74
- action_name == 'new' ? nil : create_resource_params
78
+ action_name == "new" ? nil : create_resource_params
75
79
  end
76
80
 
77
81
  ##
78
82
  # Permitted params for `create` action
79
83
  #
80
84
  # Permitted params for the `create` action scoped to the resource.
81
- #
82
85
  def create_resource_params
83
86
  permitted = permitted_create_attributes
84
87
 
85
- params.require(resource_scope).permit(permitted)
88
+ params.require(model_scope).permit(permitted)
86
89
  end
87
90
 
88
91
  ##
89
92
  # Permitted params for `update` action
90
93
  #
91
94
  # Permitted params for the `update` action scoped to the resource.
92
- #
93
95
  def update_resource_params
94
96
  permitted = permitted_update_attributes
95
97
 
96
- params.require(resource_scope).permit(permitted)
98
+ params.require(model_scope).permit(permitted)
97
99
  end
98
100
 
99
101
  private
100
102
 
103
+ ##
104
+ # Permitted attributes fallback
105
+ #
106
+ # Falls back to the controller's `permitted_attributes` method, if defined, when
107
+ # `permitted_create_attributes`/`permitted_update_attributes` are not individually overridden.
108
+ #
109
+ # @return [Array,Hash] permitted attributes, or an empty array if `permitted_attributes` is not defined
101
110
  def permitted_attributes_fallback
102
- with_method = self.class.instance_methods(false).include?(:permitted_attributes)
111
+ with_method = self.class.method_defined?(:permitted_attributes)
103
112
 
104
113
  with_method ? permitted_attributes : []
105
114
  end
@@ -10,11 +10,12 @@ module Undercarriage
10
10
  #
11
11
  # Utility helper methods
12
12
  #
13
- # Usage
13
+ # UtilityConcern is not meant to be included alone
14
+ #
15
+ # @example Controller
14
16
  # class ExamplesController < ApplicationController
15
- # include Undercarriage::Controllers::Restful::UtilityConcern
17
+ # include Undercarriage::Controllers::RestfulConcern
16
18
  # end
17
- #
18
19
  module UtilityConcern
19
20
  extend ActiveSupport::Concern
20
21
 
@@ -23,6 +24,7 @@ module Undercarriage
23
24
  ##
24
25
  # Singular controller name
25
26
  #
27
+ # @return [String] singular controller name
26
28
  def controller_name_singular
27
29
  controller_name.to_s.singularize
28
30
  end
@@ -30,6 +32,7 @@ module Undercarriage
30
32
  ##
31
33
  # Titleized controller name
32
34
  #
35
+ # @return [String] titelized controller name
33
36
  def controller_name_singular_title
34
37
  controller_name_singular.titleize
35
38
  end
@@ -38,6 +41,7 @@ module Undercarriage
38
41
  ##
39
42
  # Model name
40
43
  #
44
+ # @return [String] model name
41
45
  def model_name
42
46
  controller_name_singular
43
47
  end
@@ -45,13 +49,23 @@ module Undercarriage
45
49
  ##
46
50
  # Model class
47
51
  #
52
+ # @return [Object] model class
48
53
  def model_class
49
54
  model_name.classify.constantize
50
55
  end
51
56
 
57
+ ##
58
+ # Model scope
59
+ #
60
+ # @return [Symbol] model scope
61
+ def model_scope
62
+ model_name.to_sym
63
+ end
64
+
52
65
  ##
53
66
  # Instances name
54
67
  #
68
+ # @return [String] instances name
55
69
  def instances_name
56
70
  controller_name.to_s
57
71
  end
@@ -59,16 +73,10 @@ module Undercarriage
59
73
  ##
60
74
  # Instance name
61
75
  #
76
+ # @return [String] instance name
62
77
  def instance_name
63
78
  model_name
64
79
  end
65
-
66
- ##
67
- # Resource scope
68
- #
69
- def resource_scope
70
- model_name.to_sym
71
- end
72
80
  end
73
81
  end
74
82
  end
@@ -6,21 +6,14 @@ module Undercarriage
6
6
  ##
7
7
  # Restful actions
8
8
  #
9
- # Usage
9
+ # @example Controller
10
10
  # class ExamplesController < ApplicationController
11
11
  # include Undercarriage::Controllers::RestfulConcern
12
12
  # end
13
- #
14
13
  module RestfulConcern
15
14
  extend ActiveSupport::Concern
16
15
 
17
16
  included do
18
- include Undercarriage::Controllers::Restful::FlashConcern
19
- include Undercarriage::Controllers::Restful::LocationAfterConcern
20
- include Undercarriage::Controllers::Restful::NamespaceConcern
21
- include Undercarriage::Controllers::Restful::PermittedAttributesConcern
22
- include Undercarriage::Controllers::Restful::UtilityConcern
23
- include Undercarriage::Controllers::Restful::Actions::BaseConcern
24
17
  include Undercarriage::Controllers::Restful::Actions::IndexConcern
25
18
  include Undercarriage::Controllers::Restful::Actions::ShowConcern
26
19
  include Undercarriage::Controllers::Restful::Actions::NewConcern
@@ -10,78 +10,78 @@ module Undercarriage
10
10
  # datetime in the column, it is considered published. You need to do your own validation to ensure the value is a
11
11
  # datetime value
12
12
  #
13
- # Usage
14
- # # Model
13
+ # @example Model
15
14
  # class Example < ApplicationRecord
16
15
  # include Undercarriage::Models::PublishedConcern
17
16
  #
18
17
  # ##
19
18
  # # The name of the column is expected to be `published_at`. If that is not the case for you, uncomment the
20
19
  # # following to change the column name
21
- # #
22
20
  # # self.published_column = :ready_at
23
21
  #
24
22
  # ##
25
23
  # # The following are useful helpers for the model. They are not part of the concern
26
- # #
27
24
  # scope :available, -> { published.where("#{published_column} <= ?", Time.current) }
28
25
  #
29
26
  # def available?
30
27
  # published? && self[published_column] <= Time.current
31
28
  # end
32
29
  #
33
- # scope :scheduled, -> { published.where("#{published_column} > ?", , Time.current) }
30
+ # scope :scheduled, -> { published.where("#{published_column} > ?", Time.current) }
34
31
  #
35
32
  # def scheduled?
36
33
  # published? && self[published_column] > Time.current
37
34
  # end
38
35
  # end
39
36
  #
40
- # # Controller
41
- # class PagesController < AdminController
37
+ # @example Controller
38
+ # class ExamplesController < ApplicationController
42
39
  # def index
43
40
  # @examples = Example.published
44
41
  # end
45
42
  # end
46
43
  #
47
- # # View
48
- # <% @examples.each do |example| %>
49
- # Published?: <%= example.published? %>
50
- # <% end %>
51
- #
44
+ # @example View
45
+ # # <% @examples.each do |example| %>
46
+ # # Published?: <%= example.published? %>
47
+ # # <% end %>
52
48
  module PublishedConcern
53
49
  extend ActiveSupport::Concern
54
50
 
51
+ ##
52
+ # @!method self.published
53
+ # Published scope
54
+ #
55
+ # Retrieve only published resources
56
+ #
57
+ # @return [ActiveRecord::Relation] published resources
58
+ #
59
+ # @example Controller
60
+ # class ExamplesController < ApplicationController
61
+ # def index
62
+ # @examples = Example.published
63
+ # end
64
+ # end
65
+
66
+ ##
67
+ # @!method self.unpublished
68
+ # Unpublished scope
69
+ #
70
+ # Retrieve only unpublished resources
71
+ #
72
+ # @return [ActiveRecord::Relation] unpublished resources
73
+ #
74
+ # @example Controller
75
+ # class ExamplesController < ApplicationController
76
+ # def index
77
+ # @examples = Example.unpublished
78
+ # end
79
+ # end
55
80
  included do
56
81
  class_attribute :published_column
57
82
  self.published_column = :published_at
58
83
 
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
84
  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
85
  scope :unpublished, -> { where(published_column => nil) }
86
86
  end
87
87
 
@@ -91,12 +91,11 @@ module Undercarriage
91
91
  # Check if an item is published based on the presence of a value in the published column. This does not take into
92
92
  # account whether the item is not currently available (scheduled). See module documentation for more information
93
93
  #
94
- # Usage
95
- # @example.published? => true
96
- # @example.published? => false
97
- #
98
94
  # @return [Boolean] if resource is published
99
95
  #
96
+ # @example Controller or View
97
+ # @example.published? => true
98
+ # @example.published? => false
100
99
  def published?
101
100
  self[self.class.published_column].present?
102
101
  end
@@ -106,12 +105,11 @@ module Undercarriage
106
105
  #
107
106
  # Check if an item is unpublished based on the lack of presence of a value in the published column
108
107
  #
109
- # Usage
110
- # @example.unpublished? => true
111
- # @example.unpublished? => false
112
- #
113
108
  # @return [Boolean] if resource is unpublished
114
109
  #
110
+ # @example Controller or View
111
+ # @example.unpublished? => true
112
+ # @example.unpublished? => false
115
113
  def unpublished?
116
114
  !published?
117
115
  end
@@ -3,6 +3,5 @@
3
3
  module Undercarriage
4
4
  ##
5
5
  # Undercarriage version
6
- #
7
- VERSION = '0.5.5'
6
+ VERSION = "1.0.0"
8
7
  end
data/lib/undercarriage.rb CHANGED
@@ -1,28 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'undercarriage/controllers/action_concern'
4
- require 'undercarriage/controllers/kaminari_concern'
5
- require 'undercarriage/controllers/locale_concern'
6
- require 'undercarriage/controllers/restful_concern'
7
- require 'undercarriage/controllers/restful/actions/base_concern'
8
- require 'undercarriage/controllers/restful/actions/index_concern'
9
- require 'undercarriage/controllers/restful/actions/show_concern'
10
- require 'undercarriage/controllers/restful/actions/new_concern'
11
- require 'undercarriage/controllers/restful/actions/create_concern'
12
- require 'undercarriage/controllers/restful/actions/edit_concern'
13
- require 'undercarriage/controllers/restful/actions/update_concern'
14
- require 'undercarriage/controllers/restful/actions/destroy_concern'
15
- require 'undercarriage/controllers/restful/flash_concern'
16
- require 'undercarriage/controllers/restful/location_after_concern'
17
- require 'undercarriage/controllers/restful/namespace_concern'
18
- require 'undercarriage/controllers/restful/permitted_attributes_concern'
19
- require 'undercarriage/controllers/restful/utility_concern'
20
- require 'undercarriage/models/published_concern'
3
+ require "undercarriage/controllers/action_concern"
4
+ require "undercarriage/controllers/kaminari_concern"
5
+ require "undercarriage/controllers/locale_concern"
6
+ require "undercarriage/controllers/restful_concern"
7
+ require "undercarriage/controllers/restful/actions/base_concern"
8
+ require "undercarriage/controllers/restful/actions/index_concern"
9
+ require "undercarriage/controllers/restful/actions/show_concern"
10
+ require "undercarriage/controllers/restful/actions/new_concern"
11
+ require "undercarriage/controllers/restful/actions/create_concern"
12
+ require "undercarriage/controllers/restful/actions/edit_concern"
13
+ require "undercarriage/controllers/restful/actions/update_concern"
14
+ require "undercarriage/controllers/restful/actions/destroy_concern"
15
+ require "undercarriage/controllers/restful/flash_concern"
16
+ require "undercarriage/controllers/restful/location_after_concern"
17
+ require "undercarriage/controllers/restful/namespace_concern"
18
+ require "undercarriage/controllers/restful/permitted_attributes_concern"
19
+ require "undercarriage/controllers/restful/utility_concern"
20
+ require "undercarriage/models/published_concern"
21
21
 
22
22
  ##
23
23
  # Undercarriage
24
24
  #
25
25
  # Undercarriage is a set of concerns to add to your application to trim some of the fat from controllers and models.
26
- #
27
26
  module Undercarriage
28
27
  end