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.
- checksums.yaml +4 -4
- data/README.md +42 -1
- data/app/controllers/wallaby/resources_controller.rb +15 -375
- data/app/security/ability.rb +1 -1
- data/config/locales/wallaby.en.yml +92 -128
- data/config/locales/wallaby_class.en.yml +2 -23
- data/lib/adaptors/wallaby/custom/default_provider.rb +1 -1
- data/lib/adaptors/wallaby/custom/model_decorator.rb +8 -7
- data/lib/adaptors/wallaby/custom/model_finder.rb +3 -2
- data/lib/adaptors/wallaby/custom/model_pagination_provider.rb +1 -1
- data/lib/adaptors/wallaby/custom/model_service_provider.rb +1 -40
- data/lib/authorizers/wallaby/cancancan_authorization_provider.rb +30 -24
- data/lib/authorizers/wallaby/default_authorization_provider.rb +6 -13
- data/lib/authorizers/wallaby/model_authorizer.rb +43 -67
- data/lib/authorizers/wallaby/pundit_authorization_provider.rb +21 -30
- data/lib/concerns/wallaby/application_concern.rb +110 -0
- data/lib/concerns/wallaby/authentication_concern.rb +162 -0
- data/lib/concerns/wallaby/authorizable.rb +8 -8
- data/lib/concerns/wallaby/baseable.rb +91 -10
- data/lib/concerns/wallaby/decoratable.rb +3 -3
- data/lib/concerns/wallaby/engineable.rb +1 -1
- data/lib/concerns/wallaby/fieldable.rb +4 -4
- data/lib/concerns/wallaby/paginatable.rb +3 -3
- data/lib/concerns/wallaby/resourcable.rb +4 -35
- data/lib/concerns/wallaby/resources_concern.rb +434 -0
- data/lib/concerns/wallaby/servicable.rb +4 -4
- data/lib/decorators/wallaby/resource_decorator.rb +53 -80
- data/lib/errors/wallaby/class_not_found.rb +6 -0
- data/lib/errors/wallaby/model_not_found.rb +3 -1
- data/lib/errors/wallaby/resource_not_found.rb +1 -1
- data/lib/helpers/wallaby/application_helper.rb +6 -0
- data/lib/helpers/wallaby/form_helper.rb +2 -3
- data/lib/helpers/wallaby/index_helper.rb +2 -2
- data/lib/helpers/wallaby/links_helper.rb +5 -5
- data/lib/helpers/wallaby/resources_helper.rb +3 -0
- data/lib/helpers/wallaby/secure_helper.rb +3 -3
- data/lib/helpers/wallaby/styling_helper.rb +17 -3
- data/lib/interfaces/wallaby/mode.rb +5 -5
- data/lib/interfaces/wallaby/model_authorization_provider.rb +15 -13
- data/lib/interfaces/wallaby/model_decorator.rb +15 -3
- data/lib/paginators/wallaby/model_paginator.rb +14 -45
- data/lib/routes/wallaby/resources_router.rb +1 -1
- data/lib/servicers/wallaby/model_servicer.rb +32 -62
- data/lib/services/wallaby/map/mode_mapper.rb +14 -14
- data/lib/services/wallaby/map/model_class_collector.rb +2 -2
- data/lib/services/wallaby/map/model_class_mapper.rb +7 -26
- data/lib/services/wallaby/type_renderer.rb +2 -12
- data/lib/utils/wallaby/locale.rb +53 -0
- data/lib/utils/wallaby/model_utils.rb +4 -3
- data/lib/utils/wallaby/module_utils.rb +1 -1
- data/lib/utils/wallaby/utils.rb +23 -9
- data/lib/wallaby/class_array.rb +75 -0
- data/lib/wallaby/class_hash.rb +94 -0
- data/lib/wallaby/classifier.rb +29 -0
- data/lib/wallaby/configuration/mapping.rb +33 -21
- data/lib/wallaby/configuration/metadata.rb +1 -1
- data/lib/wallaby/configuration/models.rb +5 -9
- data/lib/wallaby/configuration/security.rb +6 -3
- data/lib/wallaby/configuration/sorting.rb +1 -1
- data/lib/wallaby/configuration.rb +31 -2
- data/lib/wallaby/core/version.rb +1 -1
- data/lib/wallaby/core.rb +18 -6
- data/lib/wallaby/engine.rb +9 -20
- data/lib/wallaby/logger.rb +35 -0
- data/lib/wallaby/map.rb +20 -17
- data/lib/wallaby/preloader.rb +77 -0
- metadata +16 -9
- data/app/controllers/wallaby/application_controller.rb +0 -84
- data/app/controllers/wallaby/secure_controller.rb +0 -81
- 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
|
-
|
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
|
-
#
|
5
|
-
#
|
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
|
-
#
|
16
|
-
|
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
|
64
|
+
return if model_class.blank?
|
92
65
|
|
93
|
-
Map.model_decorator_map model_class,
|
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
|
-
|
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 =
|
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
|
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
|
@@ -5,7 +5,9 @@ module Wallaby
|
|
5
5
|
class ModelNotFound < NotFound
|
6
6
|
# @return [String] not found error message
|
7
7
|
def message
|
8
|
-
|
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
|
@@ -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 &&
|
50
|
-
|
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
|