wallaby-core 0.2.0 → 0.2.1

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/wallaby/resources_controller.rb +6 -375
  3. data/app/security/ability.rb +1 -1
  4. data/config/locales/wallaby.en.yml +92 -128
  5. data/config/locales/wallaby_class.en.yml +0 -21
  6. data/lib/adaptors/wallaby/custom/model_service_provider.rb +8 -8
  7. data/lib/authorizers/wallaby/cancancan_authorization_provider.rb +2 -1
  8. data/lib/authorizers/wallaby/pundit_authorization_provider.rb +2 -2
  9. data/lib/concerns/wallaby/application_concern.rb +111 -0
  10. data/lib/concerns/wallaby/authentication_concern.rb +93 -0
  11. data/lib/concerns/wallaby/authorizable.rb +1 -1
  12. data/lib/concerns/wallaby/decoratable.rb +1 -1
  13. data/lib/concerns/wallaby/paginatable.rb +1 -1
  14. data/lib/concerns/wallaby/resourcable.rb +4 -0
  15. data/lib/concerns/wallaby/resources_concern.rb +433 -0
  16. data/lib/concerns/wallaby/servicable.rb +1 -1
  17. data/lib/errors/wallaby/model_not_found.rb +1 -1
  18. data/lib/errors/wallaby/resource_not_found.rb +1 -1
  19. data/lib/helpers/wallaby/application_helper.rb +6 -0
  20. data/lib/helpers/wallaby/form_helper.rb +2 -3
  21. data/lib/helpers/wallaby/index_helper.rb +2 -2
  22. data/lib/helpers/wallaby/links_helper.rb +5 -5
  23. data/lib/helpers/wallaby/styling_helper.rb +17 -3
  24. data/lib/interfaces/wallaby/mode.rb +2 -2
  25. data/lib/interfaces/wallaby/model_decorator.rb +1 -1
  26. data/lib/paginators/wallaby/model_paginator.rb +1 -1
  27. data/lib/routes/wallaby/resources_router.rb +1 -1
  28. data/lib/servicers/wallaby/model_servicer.rb +2 -1
  29. data/lib/services/wallaby/map/model_class_collector.rb +1 -1
  30. data/lib/services/wallaby/type_renderer.rb +2 -2
  31. data/lib/utils/wallaby/locale.rb +53 -0
  32. data/lib/utils/wallaby/logger.rb +21 -0
  33. data/lib/utils/wallaby/model_utils.rb +1 -1
  34. data/lib/utils/wallaby/module_utils.rb +1 -1
  35. data/lib/utils/wallaby/utils.rb +1 -1
  36. data/lib/wallaby/core.rb +6 -0
  37. data/lib/wallaby/core/version.rb +1 -1
  38. data/lib/wallaby/engine.rb +3 -3
  39. data/lib/wallaby/map.rb +1 -1
  40. metadata +7 -4
  41. data/app/controllers/wallaby/application_controller.rb +0 -84
  42. data/app/controllers/wallaby/secure_controller.rb +0 -81
@@ -1,24 +1,3 @@
1
- # Files in the config/locales directory are used for internationalization
2
- # and are automatically loaded by Rails. If you want to use locales other
3
- # than English, add the necessary files in this directory.
4
- #
5
- # To use the locales, use `I18n.t`:
6
- #
7
- # I18n.t 'hello'
8
- #
9
- # In views, this is aliased to just `t`:
10
- #
11
- # <%= t('hello') %>
12
- #
13
- # To use a different locale, set it with `I18n.locale`:
14
- #
15
- # I18n.locale = :es
16
- #
17
- # This would use the information in config/locales/es.yml.
18
- #
19
- # To learn more, please read the Rails Internationalization guide
20
- # available at http://guides.rubyonrails.org/i18n.html.
21
-
22
1
  en:
23
2
  wallaby:
24
3
  map:
@@ -6,42 +6,42 @@ module Wallaby
6
6
  class ModelServiceProvider < ::Wallaby::ModelServiceProvider
7
7
  # @raise [Wallaby::NotImplemented]
8
8
  def permit(*)
9
- raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
9
+ raise Wallaby::NotImplemented, Locale.t('errors.not_implemented.model_servicer', method_name: __callee__)
10
10
  end
11
11
 
12
12
  # @raise [Wallaby::NotImplemented]
13
13
  def collection(*)
14
- raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
14
+ raise Wallaby::NotImplemented, Locale.t('errors.not_implemented.model_servicer', method_name: __callee__)
15
15
  end
16
16
 
17
17
  # @raise [Wallaby::NotImplemented]
18
18
  def paginate(*)
19
- raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
19
+ raise Wallaby::NotImplemented, Locale.t('errors.not_implemented.model_servicer', method_name: __callee__)
20
20
  end
21
21
 
22
22
  # @raise [Wallaby::NotImplemented]
23
23
  def new(*)
24
- raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
24
+ raise Wallaby::NotImplemented, Locale.t('errors.not_implemented.model_servicer', method_name: __callee__)
25
25
  end
26
26
 
27
27
  # @raise [Wallaby::NotImplemented]
28
28
  def find(*)
29
- raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
29
+ raise Wallaby::NotImplemented, Locale.t('errors.not_implemented.model_servicer', method_name: __callee__)
30
30
  end
31
31
 
32
32
  # @raise [Wallaby::NotImplemented]
33
33
  def create(*)
34
- raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
34
+ raise Wallaby::NotImplemented, Locale.t('errors.not_implemented.model_servicer', method_name: __callee__)
35
35
  end
36
36
 
37
37
  # @raise [Wallaby::NotImplemented]
38
38
  def update(*)
39
- raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
39
+ raise Wallaby::NotImplemented, Locale.t('errors.not_implemented.model_servicer', method_name: __callee__)
40
40
  end
41
41
 
42
42
  # @raise [Wallaby::NotImplemented]
43
43
  def destroy(*)
44
- raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
44
+ raise Wallaby::NotImplemented, Locale.t('errors.not_implemented.model_servicer', method_name: __callee__)
45
45
  end
46
46
  end
47
47
  end
@@ -35,7 +35,7 @@ module Wallaby
35
35
  def authorize(action, subject)
36
36
  ability.authorize! action, subject
37
37
  rescue ::CanCan::AccessDenied
38
- Rails.logger.info I18n.t('errors.unauthorized', user: user, action: action, subject: subject)
38
+ Logger.info Locale.t('errors.unauthorized', user: user, action: action, subject: subject)
39
39
  raise Forbidden
40
40
  end
41
41
 
@@ -55,6 +55,7 @@ module Wallaby
55
55
  ModuleUtils.try_to(scope, :accessible_by, ability, action) || scope
56
56
  end
57
57
 
58
+ # @!method attributes_for(action, subject)
58
59
  # Restrict user to assign certain values.
59
60
  # @param action [Symbol, String]
60
61
  # @param subject [Object]
@@ -32,7 +32,7 @@ module Wallaby
32
32
  def authorize(action, subject)
33
33
  Pundit.authorize(user, subject, normalize(action)) && subject
34
34
  rescue ::Pundit::NotAuthorizedError
35
- Rails.logger.info I18n.t('errors.unauthorized', user: user, action: action, subject: subject)
35
+ Logger.info Locale.t('errors.unauthorized', user: user, action: action, subject: subject)
36
36
  raise Forbidden
37
37
  end
38
38
 
@@ -57,7 +57,7 @@ module Wallaby
57
57
  def attributes_for(action, subject)
58
58
  policy = Pundit.policy! user, subject
59
59
  value = ModuleUtils.try_to(policy, "attributes_for_#{action}") || ModuleUtils.try_to(policy, 'attributes_for')
60
- Rails.logger.warn I18n.t('error.pundit.not_found.attributes_for', subject: subject) unless value
60
+ Logger.warn Locale.t('error.pundit.not_found.attributes_for', subject: subject) unless value
61
61
  value || {}
62
62
  end
63
63
 
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wallaby
4
+ # Here, it provides the most basic functions e.g. error handling for common 4xx HTTP status, helpers method,
5
+ # and URL handling.
6
+ module ApplicationConcern
7
+ extend ActiveSupport::Concern
8
+
9
+ # @!parse
10
+ # extend Engineable::ClassMethods
11
+ # include Engineable
12
+ # include SharedHelpers
13
+
14
+ # @!method healthy
15
+ # Health check page
16
+
17
+ # @!method not_found(exception = nil)
18
+ # Not found page
19
+ # @param exception [Exception] comes from **rescue_from**
20
+
21
+ # @!method bad_request(exception = nil)
22
+ # Bad request page
23
+ # @param exception [Exception] comes from **rescue_from**
24
+
25
+ # @!method unprocessable_entity(exception = nil)
26
+ # Unprocessable entity page
27
+ # @param exception [Exception] comes from **rescue_from**
28
+
29
+ # @!method internal_server_error(exception = nil)
30
+ # Internal server error page
31
+ # @param exception [Exception] comes from **rescue_from**
32
+
33
+ # @!method not_implemented(exception = nil)
34
+ # Not implemented
35
+ # @param exception [Exception] comes from **rescue_from**
36
+
37
+ # @!method helpers
38
+ # {https://api.rubyonrails.org/classes/ActionController/Helpers.html#method-i-helpers helpers}
39
+ # exists since Rails 5.0, need to mimic this to support Rails 4.2.
40
+ # @see https://api.rubyonrails.org/classes/ActionController/Helpers.html#method-i-helpers
41
+ # ActionController::Helpers#helpers
42
+ # @see https://github.com/rails/rails/blob/5-0-stable/actionpack/lib/action_controller/metal/helpers.rb#L118
43
+
44
+ # @!method render_error(exception, symbol)
45
+ # Capture exceptions and display the error using error template.
46
+ # @param exception [Exception]
47
+ # @param symbol [Symbol] http status symbol
48
+
49
+ included do # rubocop:disable Metrics/BlockLength
50
+ extend Engineable::ClassMethods
51
+ include Engineable
52
+ include SharedHelpers
53
+ helper ApplicationHelper
54
+
55
+ rescue_from NotFound, with: :not_found
56
+ rescue_from ::ActionController::ParameterMissing, with: :bad_request
57
+ rescue_from ::ActiveRecord::StatementInvalid, with: :unprocessable_entity
58
+ rescue_from NotImplemented, with: :not_implemented
59
+ rescue_from UnprocessableEntity, with: :unprocessable_entity
60
+
61
+ delegate(*ConfigurationHelper.instance_methods(false), :url_for, to: :helpers)
62
+
63
+ # (see #healthy)
64
+ def healthy
65
+ render plain: 'healthy'
66
+ end
67
+
68
+ # (see #not_found)
69
+ def not_found(exception = nil)
70
+ render_error exception, __callee__
71
+ end
72
+
73
+ # (see #bad_request)
74
+ def bad_request(exception = nil)
75
+ render_error exception, __callee__
76
+ end
77
+
78
+ # (see #unprocessable_entity)
79
+ def unprocessable_entity(exception = nil)
80
+ render_error exception, __callee__
81
+ end
82
+
83
+ # (see #internal_server_error)
84
+ def internal_server_error(exception = nil)
85
+ render_error exception, __callee__
86
+ end
87
+
88
+ # (see #not_implemented)
89
+ def not_implemented(exception = nil)
90
+ render_error exception, __callee__
91
+ end
92
+
93
+ # (see #helpers)
94
+ def helpers
95
+ @helpers ||= defined?(super) ? super : view_context
96
+ end
97
+
98
+ protected
99
+
100
+ # (see #render_error)
101
+ def render_error(exception, symbol)
102
+ Logger.error exception, sourcing: false
103
+
104
+ @exception = exception
105
+ @symbol = symbol
106
+ @code = Rack::Utils::SYMBOL_TO_STATUS_CODE[symbol].to_i
107
+ respond_with @exception, status: @code, template: ERROR_PATH, prefixes: _prefixes
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wallaby
4
+ # Authentication related functions
5
+ module AuthenticationConcern
6
+ extend ActiveSupport::Concern
7
+
8
+ # @!method current_user
9
+ # @note This is a template method that can be overridden by subclasses
10
+ # This {current_user} method will try to looking up the actual implementation from the following
11
+ # places from high precedence to low:
12
+ #
13
+ # - {Wallaby::Configuration::Security#current_user}
14
+ # - `super`
15
+ # - do nothing
16
+ #
17
+ # It can be replaced completely in subclasses:
18
+ #
19
+ # def current_user
20
+ # # NOTE: please ensure `@current_user` is assigned, for instance:
21
+ # @current_user ||= User.new params.slice(:email)
22
+ # end
23
+ # @return [Object] a user object
24
+
25
+ # @!method authenticate_user!
26
+ # @note This is a template method that can be overridden by subclasses
27
+ # This {authenticate_user!} method will try to looking up the actual implementation from the following
28
+ # places from high precedence to low:
29
+ #
30
+ # - {Wallaby::Configuration::Security#authenticate}
31
+ # - `super`
32
+ # - do nothing
33
+ #
34
+ # It can be replaced completely in subclasses:
35
+ #
36
+ # def authenticate_user!
37
+ # authenticate_or_request_with_http_basic do |username, password|
38
+ # username == 'too_simple' && password == 'too_naive'
39
+ # end
40
+ # end
41
+ # @return [true] when user is authenticated successfully
42
+ # @raise [Wallaby::NotAuthenticated] when user fails to authenticate
43
+
44
+ # @!method unauthorized(exception = nil)
45
+ # Unauthorized page.
46
+ # @param exception [Exception] exception comes from `rescue_from`
47
+
48
+ # @!method forbidden(exception = nil)
49
+ # Forbidden page.
50
+ # @param exception [Exception] exception comes from `rescue_from`
51
+
52
+ included do # rubocop:disable Metrics/BlockLength
53
+ helper SecureHelper
54
+ helper_method :current_user
55
+
56
+ rescue_from NotAuthenticated, with: :unauthorized
57
+ rescue_from Forbidden, with: :forbidden
58
+
59
+ # (see #current_user)
60
+ def current_user
61
+ @current_user ||=
62
+ if security.current_user? || !defined? super
63
+ instance_exec(&security.current_user)
64
+ else
65
+ super
66
+ end
67
+ end
68
+
69
+ # (see #authenticate_user!)
70
+ def authenticate_user!
71
+ authenticated =
72
+ if security.authenticate? || !defined? super
73
+ instance_exec(&security.authenticate)
74
+ else
75
+ super
76
+ end
77
+ raise NotAuthenticated unless authenticated
78
+
79
+ true
80
+ end
81
+
82
+ # (see #unauthorized)
83
+ def unauthorized(exception = nil)
84
+ render_error exception, __callee__
85
+ end
86
+
87
+ # (see #forbidden)
88
+ def forbidden(exception = nil)
89
+ render_error exception, __callee__
90
+ end
91
+ end
92
+ end
93
+ end
@@ -56,7 +56,7 @@ module Wallaby
56
56
  def current_authorizer
57
57
  @current_authorizer ||=
58
58
  authorizer_of(current_model_class, controller_to_get(:model_authorizer)).tap do |authorizer|
59
- Rails.logger.info %( - Current authorizer: #{authorizer.try(:class)})
59
+ Logger.debug %(Current authorizer: #{authorizer.try(:class)})
60
60
  end
61
61
  end
62
62
 
@@ -68,7 +68,7 @@ module Wallaby
68
68
  @current_decorator ||=
69
69
  (controller_to_get(:resource_decorator) || \
70
70
  Map.resource_decorator_map(current_model_class, controller_to_get(:application_decorator))).tap do |decorator|
71
- Rails.logger.info %( - Current decorator: #{decorator})
71
+ Logger.debug %(Current decorator: #{decorator})
72
72
  end
73
73
  end
74
74
 
@@ -53,7 +53,7 @@ module Wallaby
53
53
  @current_paginator ||=
54
54
  (controller_to_get(:model_paginator) \
55
55
  || Map.paginator_map(current_model_class, controller_to_get(:application_paginator))).try do |klass|
56
- Rails.logger.info %( - Current paginator: #{klass})
56
+ Logger.debug %(Current paginator: #{klass})
57
57
  klass.new current_model_class, collection, params
58
58
  end
59
59
  end
@@ -97,6 +97,8 @@ module Wallaby
97
97
  )
98
98
  end
99
99
 
100
+ alias collection! collection
101
+
100
102
  # @note This is a template method that can be overridden by subclasses.
101
103
  # This is a method to return resource for pages except `index`.
102
104
  #
@@ -145,5 +147,7 @@ module Wallaby
145
147
  &block
146
148
  )
147
149
  end
150
+
151
+ alias resource! resource
148
152
  end
149
153
  end
@@ -0,0 +1,433 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wallaby
4
+ # Resources concern
5
+ module ResourcesConcern
6
+ extend ActiveSupport::Concern
7
+
8
+ # @!parse
9
+ # include ApplicationConcern
10
+ # include AuthenticationConcern
11
+ # extend Authorizable::ClassMethods
12
+ # extend Baseable::ClassMethods
13
+ # extend Decoratable::ClassMethods
14
+ # extend Paginatable::ClassMethods
15
+ # extend Resourcable::ClassMethods
16
+ # extend Servicable::ClassMethods
17
+ #
18
+ # include View
19
+ # prepend Prefixable
20
+ #
21
+ # include Authorizable
22
+ # include Decoratable
23
+ # include Defaultable
24
+ # include Paginatable
25
+ # include Resourcable
26
+ # include Servicable
27
+ #
28
+ # alias index! index
29
+ # alias new! new
30
+ # alias create! create
31
+ # alias show! show
32
+ # alias edit! edit
33
+ # alias update! update
34
+ # alias destroy! destroy
35
+ # alias collection! collection
36
+ # alias resource! resource
37
+
38
+ # @!method home
39
+ # @note This is a template method that can be overridden by subclasses.
40
+ # This is an action for landing page display. It does nothing more than rendering `home` template.
41
+ #
42
+ # It can be replaced completely in subclasses as below:
43
+ #
44
+ # ```
45
+ # def home
46
+ # generate_dashboard_report
47
+ # end
48
+ # ```
49
+
50
+ # @!method index(options = {}, &block)
51
+ # @note This is a template method that can be overridden by subclasses.
52
+ # This is a resourceful action to list records that user can access.
53
+ #
54
+ # It can be customized as below in subclasses:
55
+ #
56
+ # `WARN: Please keep in mind that Wallaby User Interface requires **index**
57
+ # action to respond to **csv** and **json** format as well.`
58
+ #
59
+ # ```
60
+ # def index
61
+ # # do something before the origin action
62
+ # options = {} # NOTE: see `options` parameter for more details
63
+ # index!(options) do |format| # NOTE: this is better than using `super`
64
+ # # NOTE: this block is for `respond_with` which works similar to `respond_to`
65
+ # # customize response behaviour, or do something before the request is rendered
66
+ # end
67
+ # end
68
+ # ```
69
+ #
70
+ # Otherwise, it can be replaced completely in subclasses:
71
+ #
72
+ # `WARN: Please keep in mind that Wallaby User Interface requires **index**
73
+ # action to respond to **csv** and **json** format as well.`
74
+ #
75
+ # ```
76
+ # def index
77
+ # # NOTE: `@collection` will be used by the view, please ensure it is assigned, for example:
78
+ # @collection = Product.all
79
+ # respond_with @collection
80
+ # end
81
+ # ```
82
+ # @param options [Hash] (since 5.2.0) options for
83
+ # {https://www.rubydoc.info/gems/responders/ActionController/RespondWith#respond_with-instance_method
84
+ # respond_with}
85
+ # @yield [format] block for
86
+ # {https://www.rubydoc.info/gems/responders/ActionController/RespondWith#respond_with-instance_method
87
+ # respond_with}
88
+ # to customize response behaviour.
89
+ # @raise [Wallaby::Forbidden] if user has no access
90
+
91
+ # @!method new(options = {}, &block)
92
+ # @note This is a template method that can be overridden by subclasses.
93
+ # This is a resourceful action to show the form to create record that user is allowed to.
94
+ #
95
+ # It can be customized as below in subclasses:
96
+ #
97
+ # ```
98
+ # def new
99
+ # # do something before the origin action
100
+ # options = {} # NOTE: see `options` parameter for more details
101
+ # new!(options) do |format| # NOTE: this is better than using `super`
102
+ # # NOTE: this block is for `respond_with` which works similar to `respond_to`
103
+ # # customize response behaviour, or do something before the request is rendered
104
+ # end
105
+ # end
106
+ # ```
107
+ #
108
+ # Otherwise, it can be replaced completely in subclasses:
109
+ #
110
+ # ```
111
+ # def new
112
+ # # NOTE: `@resource` will be used by the view, please ensure it is assigned, for example:
113
+ # @resource = Product.new new_arrival: true
114
+ # end
115
+ # ```
116
+ # @param options [Hash] (since 5.2.0) options for
117
+ # {https://www.rubydoc.info/gems/responders/ActionController/RespondWith#respond_with-instance_method
118
+ # respond_with}
119
+ # @yield [format] block for
120
+ # {https://www.rubydoc.info/gems/responders/ActionController/RespondWith#respond_with-instance_method
121
+ # respond_with}
122
+ # to customize response behaviour.
123
+ # @raise [Wallaby::Forbidden] if user has no access
124
+
125
+ # @!method create(options = {}, &block)
126
+ # @note This is a template method that can be overridden by subclasses.
127
+ # This is a resourceful action to create a record that user is allowed to.
128
+ #
129
+ # If record is created successfully, user will be navigated to the record show page.
130
+ # Otherwise, the form will be shown again with error messages.
131
+ #
132
+ # It can be customized as below in subclasses:
133
+ #
134
+ # ```
135
+ # def create
136
+ # # do something before the origin action
137
+ # options = {} # NOTE: see `options` parameter for more details
138
+ # create!(options) do |format| # NOTE: this is better than using `super`
139
+ # # NOTE: this block is for `respond_with` which works similar to `respond_to`
140
+ # # customize response behaviour, or do something before the request is rendered
141
+ # end
142
+ # end
143
+ # ```
144
+ #
145
+ # Otherwise, it can be replaced completely in subclasses:
146
+ #
147
+ # ```
148
+ # def create
149
+ # # NOTE: `@resource` will be used by the view, please ensure it is assigned, for example:
150
+ # @resource = Product.new resource_params.merge(new_arrival: true)
151
+ # if @resource.save
152
+ # redirect_to helper.index_path(current_model_class)
153
+ # else
154
+ # render :new
155
+ # end
156
+ # end
157
+ # ```
158
+ # @param options [Hash] (since 5.2.0) options for
159
+ # {https://www.rubydoc.info/gems/responders/ActionController/RespondWith#respond_with-instance_method
160
+ # respond_with}. In addition, options `:params` is supported, see below
161
+ # @option options [ActionController::Parameters, Hash] :params
162
+ # permitted parameters for servicer to create the record. _(defaults to: {#resource_params})_
163
+ # @yield [format] block for
164
+ # {https://www.rubydoc.info/gems/responders/ActionController/RespondWith#respond_with-instance_method
165
+ # respond_with}
166
+ # to customize response behaviour.
167
+ # @raise [Wallaby::Forbidden] if user has no access
168
+
169
+ # @!method show(options = {}, &block)
170
+ # @note This is a template method that can be overridden by subclasses.
171
+ # This is a resourceful action to display the record details that user is allowed to.
172
+ #
173
+ # It can be customized as below in subclasses:
174
+ #
175
+ # ```
176
+ # def show
177
+ # # do something before the origin action
178
+ # options = {} # NOTE: see `options` parameter for more details
179
+ # show!(options) do |format| # NOTE: this is better than using `super`
180
+ # # NOTE: this block is for `respond_with` which works similar to `respond_to`
181
+ # # customize response behaviour, or do something before the request is rendered
182
+ # end
183
+ # end
184
+ # ```
185
+ #
186
+ # Otherwise, it can be replaced completely in subclasses:
187
+ #
188
+ # ```
189
+ # def show
190
+ # # NOTE: `@resource` will be used by the view, please ensure it is assigned, for example:
191
+ # @resource = Product.find_by_slug params[:id]
192
+ # end
193
+ # ```
194
+ # @param options [Hash] (since 5.2.0) options for
195
+ # {https://www.rubydoc.info/gems/responders/ActionController/RespondWith#respond_with-instance_method
196
+ # respond_with}
197
+ # @yield [format] block for
198
+ # {https://www.rubydoc.info/gems/responders/ActionController/RespondWith#respond_with-instance_method
199
+ # respond_with}
200
+ # to customize response behaviour.
201
+ # @raise [Wallaby::Forbidden] if user has no access
202
+
203
+ # @!method edit(options = {}, &block)
204
+ # @note This is a template method that can be overridden by subclasses.
205
+ # This is a resourceful action to show the form to edit record that user is allowed to.
206
+ #
207
+ # It can be customized as below in subclasses:
208
+ #
209
+ # ```
210
+ # def edit
211
+ # # do something before the origin action
212
+ # options = {} # NOTE: see `options` parameter for more details
213
+ # edit!(options) do |format| # NOTE: this is better than using `super`
214
+ # # NOTE: this block is for `respond_with` which works similar to `respond_to`
215
+ # # customize response behaviour, or do something before the request is rendered
216
+ # end
217
+ # end
218
+ # ```
219
+ #
220
+ # Otherwise, it can be replaced completely in subclasses:
221
+ #
222
+ # ```
223
+ # def edit
224
+ # # NOTE: `@resource` will be used by the view, please ensure it is assigned, for example:
225
+ # @resource = Product.find_by_slug params[:id]
226
+ # end
227
+ # ```
228
+ # @param options [Hash] (since 5.2.0) options for
229
+ # {https://www.rubydoc.info/gems/responders/ActionController/RespondWith#respond_with-instance_method
230
+ # respond_with}
231
+ # @yield [format] block for
232
+ # {https://www.rubydoc.info/gems/responders/ActionController/RespondWith#respond_with-instance_method
233
+ # respond_with}
234
+ # to customize response behaviour.
235
+ # @raise [Wallaby::Forbidden] if user has no access
236
+
237
+ # @!method update(options = {}, &block)
238
+ # @note This is a template method that can be overridden by subclasses.
239
+ # This is a resourceful action to update the record that user is allowed to.
240
+ #
241
+ # If record is updated successfully, user will be navigated to the record show page.
242
+ # Otherwise, the form will be shown again with error messages.
243
+ #
244
+ # It can be customized as below in subclasses:
245
+ #
246
+ # ```
247
+ # def update
248
+ # # do something before the origin action
249
+ # options = {} # NOTE: see `options` parameter for more details
250
+ # update!(options) do |format| # NOTE: this is better than using `super`
251
+ # # NOTE: this block is for `respond_with` which works similar to `respond_to`
252
+ # # customize response behaviour, or do something before the request is rendered
253
+ # end
254
+ # end
255
+ # ```
256
+ #
257
+ # Otherwise, it can be replaced completely in subclasses:
258
+ #
259
+ # ```
260
+ # def update
261
+ # # NOTE: `@resource` will be used by the view, please ensure it is assigned, for example:
262
+ # @resource = Product.find_by_slug params[:id]
263
+ # @resource.assign_attributes resource_params.merge(new_arrival: true)
264
+ # if @resource.save
265
+ # redirect_to helper.index_path(current_model_class)
266
+ # else
267
+ # render :new
268
+ # end
269
+ # end
270
+ # ```
271
+ # @param options [Hash] (since 5.2.0) options for
272
+ # {https://www.rubydoc.info/gems/responders/ActionController/RespondWith#respond_with-instance_method
273
+ # respond_with}. In addition, options `:params` is supported, see below
274
+ # @option options [ActionController::Parameters, Hash] :params
275
+ # permitted parameters for servicer to update the record. _(defaults to: {#resource_params})_
276
+ # @yield [format] block for
277
+ # {https://www.rubydoc.info/gems/responders/ActionController/RespondWith#respond_with-instance_method
278
+ # respond_with}
279
+ # to customize response behaviour.
280
+ # @raise [Wallaby::Forbidden] if user has no access
281
+
282
+ # @!method destroy(options = {}, &block)
283
+ # @note This is a template method that can be overridden by subclasses.
284
+ # This is a resourceful action to delete the record that user is allowed to.
285
+ #
286
+ # It can be customized as below in subclasses:
287
+ #
288
+ # ```
289
+ # def destroy
290
+ # # do something before the origin action
291
+ # options = {} # NOTE: see `options` parameter for more details
292
+ # destroy!(options) do |format| # NOTE: this is better than using `super`
293
+ # # NOTE: this block is for `respond_with` which works similar to `respond_to`
294
+ # # customize response behaviour, or do something before the request is rendered
295
+ # end
296
+ # end
297
+ # ```
298
+ #
299
+ # Otherwise, it can be replaced completely in subclasses:
300
+ #
301
+ # ```
302
+ # def destroy
303
+ # # NOTE: `@resource` will be used by the view, please ensure it is assigned, for example:
304
+ # @resource = Product.find_by_slug params[:id]
305
+ # @resource.destroy
306
+ # redirect_to helper.index_path(current_model_class)
307
+ # end
308
+ # ```
309
+ # @param options [Hash] (since 5.2.0) options for
310
+ # {https://www.rubydoc.info/gems/responders/ActionController/RespondWith#respond_with-instance_method
311
+ # respond_with}. In addition, options `:params` is supported, see below
312
+ # @option options [ActionController::Parameters, Hash] :params
313
+ # permitted parameters for servicer to destroy the record. _(defaults to: {#resource_params})_
314
+ # @yield [format] block for
315
+ # {https://www.rubydoc.info/gems/responders/ActionController/RespondWith#respond_with-instance_method
316
+ # respond_with}
317
+ # to customize response behaviour.
318
+ # @raise [Wallaby::Forbidden] if user has no access
319
+
320
+ # @!method resource_params
321
+ # @note This is a template method that can be overridden by subclasses.
322
+ # To whitelist the params for {#create} and {#update} actions.
323
+ #
324
+ # If Wallaby cannot generate the correct strong parameters, it can be replaced, for example:
325
+ #
326
+ # ```
327
+ # def resource_params
328
+ # params.fetch(:product, {}).permit(:name, :sku)
329
+ # end
330
+ # ```
331
+ # @return [ActionController::Parameters] whitelisted params
332
+
333
+ included do # rubocop:disable Metrics/BlockLength
334
+ include ApplicationConcern
335
+ include AuthenticationConcern
336
+
337
+ extend Authorizable::ClassMethods
338
+ extend Baseable::ClassMethods
339
+ extend Decoratable::ClassMethods
340
+ extend Paginatable::ClassMethods
341
+ extend Resourcable::ClassMethods
342
+ extend Servicable::ClassMethods
343
+
344
+ include View
345
+ prepend Prefixable
346
+
347
+ include Authorizable
348
+ include Decoratable
349
+ include Defaultable
350
+ include Paginatable
351
+ include Resourcable
352
+ include Servicable
353
+
354
+ # NOTE: to ensure Wallaby's layout
355
+ # is not inheriting from/impacted by parent controller's layout.
356
+ public_send(
357
+ # inherit? or include?
358
+ self == ResourcesController ? :layout : :theme_name=,
359
+ ResourcesController.controller_path
360
+ )
361
+
362
+ self.responder = ResourcesResponder
363
+ respond_to :html
364
+ respond_to :json
365
+ respond_to :csv
366
+ helper ResourcesHelper
367
+ before_action :authenticate_user!
368
+
369
+ def home
370
+ # do nothing
371
+ end
372
+
373
+ def index(options = {}, &block)
374
+ current_authorizer.authorize :index, current_model_class
375
+ respond_with collection, options, &block
376
+ end
377
+
378
+ alias_method :index!, :index
379
+
380
+ def new(options = {}, &block)
381
+ current_authorizer.authorize :new, resource
382
+ respond_with resource, options, &block
383
+ end
384
+
385
+ alias_method :new!, :new
386
+
387
+ def create(options = {}, &block)
388
+ set_defaults_for :create, options
389
+ current_authorizer.authorize :create, resource
390
+ current_servicer.create resource, options.delete(:params)
391
+ respond_with resource, options, &block
392
+ end
393
+
394
+ alias_method :create!, :create
395
+
396
+ def show(options = {}, &block)
397
+ current_authorizer.authorize :show, resource
398
+ respond_with resource, options, &block
399
+ end
400
+
401
+ alias_method :show!, :show
402
+
403
+ def edit(options = {}, &block)
404
+ current_authorizer.authorize :edit, resource
405
+ respond_with resource, options, &block
406
+ end
407
+
408
+ alias_method :edit!, :edit
409
+
410
+ def update(options = {}, &block)
411
+ set_defaults_for :update, options
412
+ current_authorizer.authorize :update, resource
413
+ current_servicer.update resource, options.delete(:params)
414
+ respond_with resource, options, &block
415
+ end
416
+
417
+ alias_method :update!, :update
418
+
419
+ def destroy(options = {}, &block)
420
+ set_defaults_for :destroy, options
421
+ current_authorizer.authorize :destroy, resource
422
+ current_servicer.destroy resource, options.delete(:params)
423
+ respond_with resource, options, &block
424
+ end
425
+
426
+ alias_method :destroy!, :destroy
427
+
428
+ def resource_params
429
+ @resource_params ||= current_servicer.permit params, action_name
430
+ end
431
+ end
432
+ end
433
+ end