wallaby-core 0.2.0 → 0.2.4

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +42 -1
  3. data/app/controllers/wallaby/resources_controller.rb +15 -375
  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 -8
  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/resourcable.rb +4 -35
  25. data/lib/concerns/wallaby/resources_concern.rb +434 -0
  26. data/lib/concerns/wallaby/servicable.rb +4 -4
  27. data/lib/decorators/wallaby/resource_decorator.rb +53 -80
  28. data/lib/errors/wallaby/class_not_found.rb +6 -0
  29. data/lib/errors/wallaby/model_not_found.rb +3 -1
  30. data/lib/errors/wallaby/resource_not_found.rb +1 -1
  31. data/lib/helpers/wallaby/application_helper.rb +6 -0
  32. data/lib/helpers/wallaby/form_helper.rb +2 -3
  33. data/lib/helpers/wallaby/index_helper.rb +2 -2
  34. data/lib/helpers/wallaby/links_helper.rb +5 -5
  35. data/lib/helpers/wallaby/resources_helper.rb +3 -0
  36. data/lib/helpers/wallaby/secure_helper.rb +3 -3
  37. data/lib/helpers/wallaby/styling_helper.rb +17 -3
  38. data/lib/interfaces/wallaby/mode.rb +5 -5
  39. data/lib/interfaces/wallaby/model_authorization_provider.rb +15 -13
  40. data/lib/interfaces/wallaby/model_decorator.rb +15 -3
  41. data/lib/paginators/wallaby/model_paginator.rb +14 -45
  42. data/lib/routes/wallaby/resources_router.rb +1 -1
  43. data/lib/servicers/wallaby/model_servicer.rb +32 -62
  44. data/lib/services/wallaby/map/mode_mapper.rb +14 -14
  45. data/lib/services/wallaby/map/model_class_collector.rb +2 -2
  46. data/lib/services/wallaby/map/model_class_mapper.rb +7 -26
  47. data/lib/services/wallaby/type_renderer.rb +2 -12
  48. data/lib/utils/wallaby/locale.rb +53 -0
  49. data/lib/utils/wallaby/model_utils.rb +4 -3
  50. data/lib/utils/wallaby/module_utils.rb +1 -1
  51. data/lib/utils/wallaby/utils.rb +23 -9
  52. data/lib/wallaby/class_array.rb +75 -0
  53. data/lib/wallaby/class_hash.rb +94 -0
  54. data/lib/wallaby/classifier.rb +29 -0
  55. data/lib/wallaby/configuration/mapping.rb +33 -21
  56. data/lib/wallaby/configuration/metadata.rb +1 -1
  57. data/lib/wallaby/configuration/models.rb +5 -9
  58. data/lib/wallaby/configuration/security.rb +6 -3
  59. data/lib/wallaby/configuration/sorting.rb +1 -1
  60. data/lib/wallaby/configuration.rb +31 -2
  61. data/lib/wallaby/core/version.rb +1 -1
  62. data/lib/wallaby/core.rb +18 -6
  63. data/lib/wallaby/engine.rb +9 -20
  64. data/lib/wallaby/logger.rb +35 -0
  65. data/lib/wallaby/map.rb +20 -17
  66. data/lib/wallaby/preloader.rb +77 -0
  67. metadata +16 -9
  68. data/app/controllers/wallaby/application_controller.rb +0 -84
  69. data/app/controllers/wallaby/secure_controller.rb +0 -81
  70. 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,12 +49,12 @@ 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
@@ -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
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wallaby
4
+ class ClassNotFound < GeneralError
5
+ end
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
@@ -66,5 +66,11 @@ module Wallaby
66
66
  options = default_options.merge!(sources.extract_options!.stringify_keys)
67
67
  super(*sources, options)
68
68
  end
69
+
70
+ # @param key
71
+ # @param options [Hash]
72
+ def wt(key, options = {})
73
+ Locale.t key, { translator: method(:t) }.merge(options)
74
+ end
69
75
  end
70
76
  end
@@ -46,9 +46,8 @@ module Wallaby
46
46
  type = metadata[:type]
47
47
  hint = metadata[:hint]
48
48
  # @see http://guides.rubyonrails.org/i18n.html#using-safe-html-translations
49
- hint ||= type && t("hints.#{type}_html", default: '').presence
50
- hint ||= type && t("hints.#{type}", default: '').presence
51
- return unless hint
49
+ hint ||= type && wt("hints.#{type}_html", default: [:"hints.#{type}", ''])
50
+ return if hint.blank?
52
51
 
53
52
  content_tag :p, hint, class: 'help-block'
54
53
  end