wallaby-core 0.1.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +60 -13
  3. data/app/controllers/wallaby/resources_controller.rb +15 -374
  4. data/app/security/ability.rb +1 -1
  5. data/config/locales/wallaby.en.yml +92 -128
  6. data/config/locales/wallaby_class.en.yml +2 -23
  7. data/lib/adaptors/wallaby/custom/default_provider.rb +1 -1
  8. data/lib/adaptors/wallaby/custom/model_decorator.rb +8 -7
  9. data/lib/adaptors/wallaby/custom/model_finder.rb +3 -2
  10. data/lib/adaptors/wallaby/custom/model_pagination_provider.rb +1 -1
  11. data/lib/adaptors/wallaby/custom/model_service_provider.rb +1 -40
  12. data/lib/authorizers/wallaby/cancancan_authorization_provider.rb +30 -24
  13. data/lib/authorizers/wallaby/default_authorization_provider.rb +6 -13
  14. data/lib/authorizers/wallaby/model_authorizer.rb +43 -67
  15. data/lib/authorizers/wallaby/pundit_authorization_provider.rb +21 -30
  16. data/lib/concerns/wallaby/application_concern.rb +110 -0
  17. data/lib/concerns/wallaby/authentication_concern.rb +162 -0
  18. data/lib/concerns/wallaby/authorizable.rb +8 -14
  19. data/lib/concerns/wallaby/baseable.rb +91 -10
  20. data/lib/concerns/wallaby/decoratable.rb +3 -3
  21. data/lib/concerns/wallaby/engineable.rb +1 -1
  22. data/lib/concerns/wallaby/fieldable.rb +4 -4
  23. data/lib/concerns/wallaby/paginatable.rb +3 -3
  24. data/lib/concerns/wallaby/prefixable.rb +21 -0
  25. data/lib/concerns/wallaby/resourcable.rb +4 -35
  26. data/lib/concerns/wallaby/resources_concern.rb +434 -0
  27. data/lib/concerns/wallaby/servicable.rb +4 -10
  28. data/lib/decorators/wallaby/resource_decorator.rb +53 -80
  29. data/lib/errors/wallaby/{cell_handling.rb → class_not_found.rb} +1 -1
  30. data/lib/errors/wallaby/model_not_found.rb +3 -1
  31. data/lib/errors/wallaby/resource_not_found.rb +1 -1
  32. data/lib/helpers/wallaby/application_helper.rb +6 -9
  33. data/lib/helpers/wallaby/form_helper.rb +2 -9
  34. data/lib/helpers/wallaby/index_helper.rb +2 -14
  35. data/lib/helpers/wallaby/links_helper.rb +5 -5
  36. data/lib/helpers/wallaby/resources_helper.rb +3 -7
  37. data/lib/helpers/wallaby/secure_helper.rb +3 -3
  38. data/lib/helpers/wallaby/styling_helper.rb +17 -3
  39. data/lib/interfaces/wallaby/mode.rb +5 -5
  40. data/lib/interfaces/wallaby/model_authorization_provider.rb +15 -13
  41. data/lib/interfaces/wallaby/model_decorator.rb +15 -3
  42. data/lib/paginators/wallaby/model_paginator.rb +14 -45
  43. data/lib/parsers/wallaby/parser.rb +49 -14
  44. data/lib/routes/wallaby/resources_router.rb +1 -1
  45. data/lib/servicers/wallaby/model_servicer.rb +32 -62
  46. data/lib/services/wallaby/map/mode_mapper.rb +14 -14
  47. data/lib/services/wallaby/map/model_class_collector.rb +2 -2
  48. data/lib/services/wallaby/map/model_class_mapper.rb +7 -26
  49. data/lib/services/wallaby/prefixes_builder.rb +15 -49
  50. data/lib/services/wallaby/type_renderer.rb +3 -13
  51. data/lib/utils/wallaby/locale.rb +53 -0
  52. data/lib/utils/wallaby/model_utils.rb +4 -3
  53. data/lib/utils/wallaby/module_utils.rb +1 -1
  54. data/lib/utils/wallaby/utils.rb +10 -15
  55. data/lib/wallaby/class_array.rb +75 -0
  56. data/lib/wallaby/class_hash.rb +94 -0
  57. data/lib/wallaby/classifier.rb +29 -0
  58. data/lib/wallaby/configuration/mapping.rb +33 -27
  59. data/lib/wallaby/configuration/metadata.rb +1 -1
  60. data/lib/wallaby/configuration/models.rb +5 -9
  61. data/lib/wallaby/configuration/security.rb +6 -3
  62. data/lib/wallaby/configuration/sorting.rb +1 -1
  63. data/lib/wallaby/configuration.rb +31 -2
  64. data/lib/wallaby/constants.rb +10 -8
  65. data/lib/wallaby/core/version.rb +1 -1
  66. data/lib/wallaby/core.rb +21 -16
  67. data/lib/wallaby/engine.rb +9 -20
  68. data/lib/wallaby/logger.rb +35 -0
  69. data/lib/wallaby/map.rb +20 -17
  70. data/lib/wallaby/preloader.rb +77 -0
  71. metadata +48 -22
  72. data/app/controllers/wallaby/application_controller.rb +0 -84
  73. data/app/controllers/wallaby/secure_controller.rb +0 -81
  74. data/lib/concerns/wallaby/rails_overridden_methods.rb +0 -42
  75. data/lib/concerns/wallaby/themeable.rb +0 -40
  76. data/lib/paginators/wallaby/resource_paginator.rb +0 -12
  77. data/lib/renderers/wallaby/cell.rb +0 -137
  78. data/lib/renderers/wallaby/cell_resolver.rb +0 -89
  79. data/lib/renderers/wallaby/custom_lookup_context.rb +0 -64
  80. data/lib/renderers/wallaby/custom_partial_renderer.rb +0 -33
  81. data/lib/renderers/wallaby/custom_renderer.rb +0 -16
  82. data/lib/utils/wallaby/cell_utils.rb +0 -34
  83. data/lib/utils/wallaby/preload_utils.rb +0 -44
@@ -0,0 +1,434 @@
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 Servicable::ClassMethods
342
+
343
+ include View
344
+ prepend Prefixable
345
+
346
+ include Authorizable
347
+ include Decoratable
348
+ include Defaultable
349
+ include Paginatable
350
+ include Resourcable
351
+ include Servicable
352
+
353
+ base_class!
354
+
355
+ # NOTE: to ensure Wallaby's layout
356
+ # is not inheriting from/impacted by parent controller's layout.
357
+ public_send(
358
+ # inherit? or include?
359
+ self == ResourcesController ? :layout : :theme_name=,
360
+ ResourcesController.controller_path
361
+ )
362
+
363
+ self.responder = ResourcesResponder
364
+ respond_to :html
365
+ respond_to :json
366
+ respond_to :csv
367
+ helper ResourcesHelper
368
+ before_action :authenticate_wallaby_user!
369
+
370
+ def home
371
+ # do nothing
372
+ end
373
+
374
+ def index(options = {}, &block)
375
+ current_authorizer.authorize :index, current_model_class
376
+ respond_with collection, options, &block
377
+ end
378
+
379
+ alias_method :index!, :index
380
+
381
+ def new(options = {}, &block)
382
+ current_authorizer.authorize :new, resource
383
+ respond_with resource, options, &block
384
+ end
385
+
386
+ alias_method :new!, :new
387
+
388
+ def create(options = {}, &block)
389
+ set_defaults_for :create, options
390
+ current_authorizer.authorize :create, resource
391
+ current_servicer.create resource, options.delete(:params)
392
+ respond_with resource, options, &block
393
+ end
394
+
395
+ alias_method :create!, :create
396
+
397
+ def show(options = {}, &block)
398
+ current_authorizer.authorize :show, resource
399
+ respond_with resource, options, &block
400
+ end
401
+
402
+ alias_method :show!, :show
403
+
404
+ def edit(options = {}, &block)
405
+ current_authorizer.authorize :edit, resource
406
+ respond_with resource, options, &block
407
+ end
408
+
409
+ alias_method :edit!, :edit
410
+
411
+ def update(options = {}, &block)
412
+ set_defaults_for :update, options
413
+ current_authorizer.authorize :update, resource
414
+ current_servicer.update resource, options.delete(:params)
415
+ respond_with resource, options, &block
416
+ end
417
+
418
+ alias_method :update!, :update
419
+
420
+ def destroy(options = {}, &block)
421
+ set_defaults_for :destroy, options
422
+ current_authorizer.authorize :destroy, resource
423
+ current_servicer.destroy resource, options.delete(:params)
424
+ respond_with resource, options, &block
425
+ end
426
+
427
+ alias_method :destroy!, :destroy
428
+
429
+ def resource_params
430
+ @resource_params ||= current_servicer.permit params, action_name
431
+ end
432
+ end
433
+ end
434
+ end
@@ -20,7 +20,7 @@ module Wallaby
20
20
  # @return [Class] model servicer
21
21
  # @raise [ArgumentError] when **model_servicer** doesn't inherit from **application_servicer**
22
22
  # @see Wallaby::ModelServicer
23
- # @since 5.2.0
23
+ # @since wallaby-5.2.0
24
24
  attr_reader :model_servicer
25
25
 
26
26
  # @!attribute [w] application_servicer
@@ -38,7 +38,7 @@ module Wallaby
38
38
  # @return [Class] application decorator
39
39
  # @raise [ArgumentError] when **model_servicer** doesn't inherit from **application_servicer**
40
40
  # @see Wallaby::ModelServicer
41
- # @since 5.2.0
41
+ # @since wallaby-5.2.0
42
42
  def application_servicer
43
43
  @application_servicer ||= ModuleUtils.try_to superclass, :application_servicer
44
44
  end
@@ -49,20 +49,14 @@ module Wallaby
49
49
  # - controller configuration {Wallaby::Servicable::ClassMethods#model_servicer .model_servicer}
50
50
  # - a generic servicer based on {Wallaby::Servicable::ClassMethods#application_servicer .application_servicer}
51
51
  # @return [Wallaby::ModelServicer] model servicer
52
- # @since 5.2.0
52
+ # @since wallaby-5.2.0
53
53
  def current_servicer
54
54
  @current_servicer ||=
55
55
  (controller_to_get(:model_servicer) \
56
56
  || Map.servicer_map(current_model_class, controller_to_get(:application_servicer))).try do |klass|
57
- Rails.logger.info %( - Current servicer: #{klass})
57
+ Logger.debug %(Current servicer: #{klass}), sourcing: false
58
58
  klass.new current_model_class, current_authorizer, current_model_decorator
59
59
  end
60
60
  end
61
-
62
- # @deprecated Use {#current_servicer} instead. It will be removed from 5.3.*
63
- def current_model_service
64
- Utils.deprecate 'deprecation.current_model_service', caller: caller
65
- current_servicer
66
- end
67
61
  end
68
62
  end
@@ -1,10 +1,53 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Wallaby
4
- # Resource Decorator base class, designed for decorator pattern.
5
- # @see Wallaby::ModelDecorator
4
+ # Decorator base class. It's designed to be used as the decorator (AKA presenter/view object)
5
+ # for the associated model instance (which means it should be used in the views only).
6
+ #
7
+ # And it holds the following metadata information for associated model class:
8
+ #
9
+ # - {#fields}
10
+ # - {#field_names}
11
+ # - {#index_fields}
12
+ # - {#index_field_names}
13
+ # - {#show_fields}
14
+ # - {#show_field_names}
15
+ # - {#form_fields}
16
+ # - {#form_field_names}
17
+ #
18
+ # For better practice, please create an application decorator class (see example)
19
+ # to better control the functions shared between different resource decorators.
20
+ # @example Create an application class for Admin Interface usage
21
+ # class Admin::ApplicationDecorator < Wallaby::ResourceDecorator
22
+ # base_class!
23
+ # end
6
24
  class ResourceDecorator
7
25
  extend Baseable::ClassMethods
26
+ base_class!
27
+
28
+ # @!attribute fields
29
+ # (see Wallaby::ModelDecorator#fields)
30
+
31
+ # @!attribute field_names
32
+ # (see Wallaby::ModelDecorator#field_names)
33
+
34
+ # @!attribute index_fields
35
+ # (see Wallaby::ModelDecorator#index_fields)
36
+
37
+ # @!attribute index_field_names
38
+ # (see Wallaby::ModelDecorator#index_field_names)
39
+
40
+ # @!attribute show_fields
41
+ # (see Wallaby::ModelDecorator#show_fields)
42
+
43
+ # @!attribute show_field_names
44
+ # (see Wallaby::ModelDecorator#show_field_names)
45
+
46
+ # @!attribute form_fields
47
+ # (see Wallaby::ModelDecorator#form_fields)
48
+
49
+ # @!attribute form_field_names
50
+ # (see Wallaby::ModelDecorator#form_field_names)
8
51
 
9
52
  DELEGATE_METHODS =
10
53
  ModelDecorator.public_instance_methods(false) + Fieldable.public_instance_methods(false) - %i(model_class)
@@ -12,85 +55,15 @@ module Wallaby
12
55
  class << self
13
56
  delegate(*DELEGATE_METHODS, to: :model_decorator, allow_nil: true)
14
57
 
15
- # @!attribute [w] model_class
16
- attr_writer :model_class
17
-
18
- # @!attribute [r] model_class
19
- # Return associated model class, e.g. return **Product** for **ProductDecorator**.
20
- #
21
- # If Wallaby can't recognise the model class for Decorator, it's required to be configured as below example:
22
- # @example To configure model class
23
- # class Admin::ProductDecorator < Admin::ApplicationDecorator
24
- # self.model_class = Product
25
- # end
26
- # @example To configure model class for version below 5.2.0
27
- # class Admin::ProductDecorator < Admin::ApplicationDecorator
28
- # def self.model_class
29
- # Product
30
- # end
31
- # end
32
- # @return [Class] assoicated model class
33
- # @return [nil] if current class is marked as base class
34
- # @return [nil] if current class is the same as the value of {Wallaby::Configuration::Mapping#resource_decorator}
35
- # @return [nil] if current class is {Wallaby::ResourceDecorator}
36
- # @return [nil] if assoicated model class is not found
37
- def model_class
38
- return unless self < ResourceDecorator
39
- return if base_class? || self == Wallaby.configuration.mapping.resource_decorator
40
-
41
- @model_class ||= Map.model_class_map(name.gsub(/(^#{namespace}::)|(Decorator$)/, EMPTY_STRING))
42
- end
43
-
44
- # @!attribute [w] application_decorator
45
- def application_decorator=(application_decorator)
46
- ModuleUtils.inheritance_check self, application_decorator
47
- @application_decorator = application_decorator
48
- end
49
-
50
- # @note This attribute have to be the same as the one defined in the controller in order to make things working.
51
- # see {Wallaby::Decoratable::ClassMethods#application_decorator}
52
- # @!attribute [r] application_decorator
53
- # Assoicated base class.
54
- #
55
- # Wallaby will try to get the application decorator class from current class's ancestors chain.
56
- # For instance, if current class is **ProductDecorator**, and it inherits from **CoreDecorator**,
57
- # then Wallaby will return application decorator class **CoreDecorator**.
58
- #
59
- # However, there is a chance that Wallaby doesn't get it right.
60
- # For instance, if **CoreDecorator** in the above example inherits from **Admin::ApplicationDecorator**, and
61
- # the controller that needs **ProductDecorator** has set its **application_decorator** to
62
- # **Admin::ApplicationDecorator**, then it's needed to configure **application_decorator** as the example
63
- # describes
64
- # @example To set application decorator class
65
- # class ProductController < Admin::ApplicationController
66
- # self.application_decorator = Admin::ApplicationDecorator
67
- # end
68
- #
69
- # class CoreDecorator < Admin::ApplicationDecorator
70
- # base_class!
71
- # end
72
- #
73
- # class ProductDecorator < CoreDecorator
74
- # self.application_decorator = Admin::ApplicationDecorator
75
- # end
76
- # @return [Class] assoicated base class.
77
- # @return [nil] if assoicated base class is not found from its ancestors chain
78
- # @raise [ArgumentError] when current class doesn't inherit from given value
79
- # @since 5.2.0
80
- def application_decorator
81
- @application_decorator ||= ancestors.find { |parent| parent < ResourceDecorator && !parent.model_class }
82
- end
83
-
84
- # Return associated model decorator.
85
- #
86
- # Fetch model decorator instance from cached map using keys {.model_class} and {.application_decorator}
87
- # so that model decorator can be used in its sub classes declaration/scope.
58
+ # Return associated model decorator. It is the instance that pull out all the metadata
59
+ # information for the associated model.
88
60
  # @param model_class [Class]
89
61
  # @return [Wallaby::ModelDecorator]
62
+ # @return [nil] if itself is a base class or the given model_class is blank
90
63
  def model_decorator(model_class = self.model_class)
91
- return unless self < ResourceDecorator || model_class
64
+ return if model_class.blank?
92
65
 
93
- Map.model_decorator_map model_class, application_decorator
66
+ Map.model_decorator_map model_class, base_class
94
67
  end
95
68
 
96
69
  # @!attribute [w] h
@@ -164,13 +137,13 @@ module Wallaby
164
137
 
165
138
  # @return [ActiveModel::Name]
166
139
  def model_name
167
- ModuleUtils.try_to(resource, :model_name) || ActiveModel::Name.new(model_class)
140
+ resource.try(:model_name) || ActiveModel::Name.new(model_class)
168
141
  end
169
142
 
170
143
  # @return [nil] if no primary key
171
144
  # @return [Array<String>] primary key
172
145
  def to_key
173
- key = ModuleUtils.try_to(resource, primary_key)
146
+ key = resource.try primary_key
174
147
  key ? [key] : nil
175
148
  end
176
149
 
@@ -181,7 +154,7 @@ module Wallaby
181
154
  resource.try method_id, *args, &block
182
155
  end
183
156
 
184
- # Delegate missing method check to context
157
+ # Delegate missing method check to {#resource}
185
158
  def respond_to_missing?(method_id, _include_private)
186
159
  resource.respond_to?(method_id) || super
187
160
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Wallaby
4
- class CellHandling < ::StandardError
4
+ class ClassNotFound < GeneralError
5
5
  end
6
6
  end
@@ -5,7 +5,9 @@ module Wallaby
5
5
  class ModelNotFound < NotFound
6
6
  # @return [String] not found error message
7
7
  def message
8
- I18n.t 'errors.not_found.model', model: super
8
+ return super if super.include? "\n"
9
+
10
+ Locale.t 'errors.not_found.model', model: super
9
11
  end
10
12
  end
11
13
  end
@@ -5,7 +5,7 @@ module Wallaby
5
5
  class ResourceNotFound < NotFound
6
6
  # @return [String] resource not found error message
7
7
  def message
8
- I18n.t 'errors.not_found.resource', resource: super
8
+ Locale.t 'errors.not_found.resource', resource: super
9
9
  end
10
10
  end
11
11
  end