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
@@ -6,7 +6,7 @@ module Wallaby
|
|
6
6
|
# Just a label
|
7
7
|
# @return [String]
|
8
8
|
def all_label
|
9
|
-
|
9
|
+
wt 'filters.all'
|
10
10
|
end
|
11
11
|
|
12
12
|
# If `:fields` parameter is given, only display fields that is in `index_field_names`
|
@@ -58,7 +58,7 @@ module Wallaby
|
|
58
58
|
# @return [String] Export link for the given model_class.
|
59
59
|
def export_link(model_class, url_params: {})
|
60
60
|
index_link(model_class, url_params: { format: 'csv', page: nil, per: nil, with_query: true }.merge(url_params)) do
|
61
|
-
|
61
|
+
wt 'links.export', ext: 'CSV'
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
@@ -44,7 +44,7 @@ module Wallaby
|
|
44
44
|
html_options, block = LinkOptionsNormalizer.normalize(
|
45
45
|
html_options, block,
|
46
46
|
class: 'resource__create',
|
47
|
-
block: -> {
|
47
|
+
block: -> { wt 'links.new', model: to_model_label(model_class) }
|
48
48
|
)
|
49
49
|
|
50
50
|
url = options[:url] || new_path(model_class, url_params: url_params)
|
@@ -97,7 +97,7 @@ module Wallaby
|
|
97
97
|
html_options, block = LinkOptionsNormalizer.normalize(
|
98
98
|
html_options, block,
|
99
99
|
class: 'resource__update',
|
100
|
-
block: -> { "#{
|
100
|
+
block: -> { "#{wt 'links.edit'} #{decorate(resource).to_label}" }
|
101
101
|
)
|
102
102
|
|
103
103
|
default = options[:readonly] && block.call || nil
|
@@ -123,11 +123,11 @@ module Wallaby
|
|
123
123
|
return if unauthorized? :destroy, extract(resource)
|
124
124
|
|
125
125
|
html_options, block = LinkOptionsNormalizer.normalize(
|
126
|
-
html_options, block, class: 'resource__destroy', block: -> {
|
126
|
+
html_options, block, class: 'resource__destroy', block: -> { wt 'links.delete' }
|
127
127
|
)
|
128
128
|
|
129
129
|
html_options[:method] ||= :delete
|
130
|
-
(html_options[:data] ||= {})[:confirm] ||=
|
130
|
+
(html_options[:data] ||= {})[:confirm] ||= wt 'links.confirm.delete'
|
131
131
|
|
132
132
|
url = options[:url] || show_path(resource, is_resource: options[:is_resource], url_params: url_params)
|
133
133
|
link_to url, html_options, &block
|
@@ -140,7 +140,7 @@ module Wallaby
|
|
140
140
|
# @yield block to return the link label
|
141
141
|
# @return [String] anchor link of cancel action
|
142
142
|
def cancel_link(html_options: {}, &block)
|
143
|
-
block ||= -> {
|
143
|
+
block ||= -> { wt 'links.cancel' }
|
144
144
|
link_to 'javascript:history.back()', html_options, &block
|
145
145
|
end
|
146
146
|
|
@@ -9,7 +9,7 @@ module Wallaby
|
|
9
9
|
# - otherwise, an user icon will be returned
|
10
10
|
# @param user [Object]
|
11
11
|
# @return [String] IMG or I element
|
12
|
-
def user_portrait(user =
|
12
|
+
def user_portrait(user = wallaby_user)
|
13
13
|
email_method = security.email_method || :email
|
14
14
|
email = try_to user, email_method
|
15
15
|
if email.present?
|
@@ -27,7 +27,7 @@ module Wallaby
|
|
27
27
|
# @param user [Object]
|
28
28
|
# @param app [Object]
|
29
29
|
# @return [String] URL to log out
|
30
|
-
def logout_path(user =
|
30
|
+
def logout_path(user = wallaby_user, app = main_app)
|
31
31
|
path = security.logout_path
|
32
32
|
path ||=
|
33
33
|
if defined? ::Devise
|
@@ -41,7 +41,7 @@ module Wallaby
|
|
41
41
|
# @see Wallaby::Configuration::Security#logout_method
|
42
42
|
# @param user [Object]
|
43
43
|
# @return [String, Symbol] http method to log out
|
44
|
-
def logout_method(user =
|
44
|
+
def logout_method(user = wallaby_user)
|
45
45
|
http_method = security.logout_method
|
46
46
|
http_method ||
|
47
47
|
if defined? ::Devise
|
@@ -3,6 +3,20 @@
|
|
3
3
|
module Wallaby
|
4
4
|
# Helper methods to build custom elements
|
5
5
|
module StylingHelper
|
6
|
+
# backforward compatible with FontAwesome 4
|
7
|
+
# @see this fa migration document https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4
|
8
|
+
FONT_AWESOME_MAPPING = {
|
9
|
+
4 => {
|
10
|
+
clock: 'clock-o',
|
11
|
+
bars: 'navicon',
|
12
|
+
calendar: 'calendar-o',
|
13
|
+
'check-square': 'check-square-o',
|
14
|
+
square: 'square-o',
|
15
|
+
link: 'chain',
|
16
|
+
user: 'user-o'
|
17
|
+
}
|
18
|
+
}.with_indifferent_access.freeze
|
19
|
+
|
6
20
|
# Shortcut to build up the HTML options as keyword arguments
|
7
21
|
# @param string_or_array [String, Array<String>]
|
8
22
|
# @param options [Hash]
|
@@ -54,12 +68,12 @@ module Wallaby
|
|
54
68
|
|
55
69
|
# @return [String] grey null
|
56
70
|
def null
|
57
|
-
muted
|
71
|
+
muted wt 'labels.empty'
|
58
72
|
end
|
59
73
|
|
60
74
|
# @return [String] grey N/A
|
61
75
|
def na
|
62
|
-
muted
|
76
|
+
muted wt 'labels.na'
|
63
77
|
end
|
64
78
|
|
65
79
|
# Grey text
|
@@ -74,7 +88,7 @@ module Wallaby
|
|
74
88
|
def fa_map(name, major = nil)
|
75
89
|
@map ||= begin
|
76
90
|
major ||= Gem.loaded_specs['font-awesome-sass'].try(:version).try(:segments).try(:first)
|
77
|
-
|
91
|
+
FONT_AWESOME_MAPPING[major] || {}
|
78
92
|
end
|
79
93
|
@map[name] || name
|
80
94
|
end
|
@@ -24,14 +24,14 @@ module Wallaby
|
|
24
24
|
|
25
25
|
# @see Wallaby::ModelPaginationProvider
|
26
26
|
# @return [Class] pagination provider for the mode
|
27
|
-
# @since 5.2.0
|
27
|
+
# @since wallaby-5.2.0
|
28
28
|
def model_pagination_provider
|
29
29
|
check_and_constantize __callee__
|
30
30
|
end
|
31
31
|
|
32
32
|
# @see Wallaby::ModelPaginationProvider
|
33
33
|
# @return [Class] pagination provider for the mode
|
34
|
-
# @since 5.2.0
|
34
|
+
# @since wallaby-5.2.0
|
35
35
|
def default_authorization_provider
|
36
36
|
check_and_constantize __callee__
|
37
37
|
end
|
@@ -39,7 +39,7 @@ module Wallaby
|
|
39
39
|
# Return a list of authorization providers for authorizer to detect which one to use.
|
40
40
|
# @see Wallaby::ModelAuthorizationProvider
|
41
41
|
# @return [ActiveSupport::HashWithIndifferentAccess<String, Class>] authorization provider hash
|
42
|
-
# @since 5.2.0
|
42
|
+
# @since wallaby-5.2.0
|
43
43
|
def model_authorization_providers(classes = ModelAuthorizationProvider.descendants)
|
44
44
|
# NOTE: make sure default provider always comes last
|
45
45
|
@model_authorization_providers ||=
|
@@ -61,10 +61,10 @@ module Wallaby
|
|
61
61
|
class_name.constantize.tap do |klass|
|
62
62
|
next if klass < parent_class
|
63
63
|
|
64
|
-
raise InvalidError,
|
64
|
+
raise InvalidError, Locale.t('mode.inherit_required', klass: klass, parent: parent_class)
|
65
65
|
end
|
66
66
|
rescue NameError => e
|
67
|
-
|
67
|
+
Logger.error e
|
68
68
|
raise NotImplemented, class_name
|
69
69
|
end
|
70
70
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Wallaby
|
4
4
|
# Model Authorizer interface.
|
5
|
-
# @since 5.2.0
|
5
|
+
# @since wallaby-5.2.0
|
6
6
|
class ModelAuthorizationProvider
|
7
7
|
class << self
|
8
8
|
# @!attribute [w] provider_name
|
@@ -13,34 +13,36 @@ module Wallaby
|
|
13
13
|
# @see Wallaby::ModelAuthorizer.provider_name
|
14
14
|
# @return [String/Symbol] provider name
|
15
15
|
def provider_name
|
16
|
-
@provider_name
|
16
|
+
@provider_name ||= name.demodulize.gsub(/(Authorization)?Provider/, EMPTY_STRING).underscore
|
17
17
|
end
|
18
18
|
|
19
19
|
# @note Template method to check and see if current provider is in used.
|
20
|
-
# @param _context [ActionController::Base]
|
20
|
+
# @param _context [ActionController::Base, ActionView::Base]
|
21
21
|
# @raise [Wallaby::NotImplemented]
|
22
22
|
def available?(_context)
|
23
23
|
raise NotImplemented
|
24
24
|
end
|
25
|
-
|
26
|
-
# @note Template method to pull out the args required for contruction from context.
|
27
|
-
# @param _context [ActionController::Base]
|
28
|
-
# @raise [Wallaby::NotImplemented]
|
29
|
-
def args_from(_context)
|
30
|
-
raise NotImplemented
|
31
|
-
end
|
32
25
|
end
|
33
26
|
|
34
27
|
# @!attribute [r] context
|
35
|
-
# @return [ActionController::Base]
|
28
|
+
# @return [ActionController::Base, ActionView::Base]
|
36
29
|
attr_reader :context
|
37
30
|
|
38
31
|
# @!attribute [r] user
|
39
32
|
# @return [Object]
|
40
33
|
attr_reader :user
|
41
34
|
|
42
|
-
#
|
43
|
-
|
35
|
+
# @!attribute [r] options
|
36
|
+
# @return [Hash]
|
37
|
+
attr_reader :options
|
38
|
+
|
39
|
+
# @param context [ActionController::Base, ActionView::Base]
|
40
|
+
# @param options [Hash]
|
41
|
+
def initialize(context, **options)
|
42
|
+
@context = context
|
43
|
+
@options = options
|
44
|
+
@user = context.try :wallaby_user
|
45
|
+
end
|
44
46
|
|
45
47
|
# @note It can be overridden in subclasses for customization purpose.
|
46
48
|
# This is the template method to check user's permission for given action on given subject.
|
@@ -157,12 +157,24 @@ module Wallaby
|
|
157
157
|
field_names.unshift(primary_key.to_s).uniq
|
158
158
|
end
|
159
159
|
|
160
|
-
#
|
160
|
+
# Ensure the type is present for given field name
|
161
161
|
# @param type [String, Symbol, nil]
|
162
162
|
# @return [String, Symbol] type
|
163
163
|
# @raise [ArgumentError] when type is nil
|
164
|
-
def
|
165
|
-
type || raise(::ArgumentError,
|
164
|
+
def ensure_type_is_present(field_name, type, metadata_prefix = '')
|
165
|
+
type || raise(::ArgumentError, <<~INSTRUCTION
|
166
|
+
The type for field `#{field_name}` is missing in metadata `#{metadata_prefix}_fields`.
|
167
|
+
The possible causes are:
|
168
|
+
|
169
|
+
1. Check type's value from metadata `#{metadata_prefix}_fields[:#{field_name}][:type]`.
|
170
|
+
If it is missing, specify the type as below:
|
171
|
+
|
172
|
+
#{metadata_prefix}field_name[:#{field_name}][:type] = 'string'
|
173
|
+
|
174
|
+
2. If metadata `#{metadata_prefix}_fields` is blank, maybe table hasn't be created yet
|
175
|
+
or there is some error in the decorator class declaration.
|
176
|
+
INSTRUCTION
|
177
|
+
)
|
166
178
|
end
|
167
179
|
end
|
168
180
|
end
|
@@ -1,72 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Wallaby
|
4
|
-
#
|
4
|
+
# This is the base paginator class to provider pagination for given collection.
|
5
|
+
#
|
6
|
+
# For best practice, please create an application paginator class (see example)
|
7
|
+
# to better control the functions shared between different model paginators.
|
8
|
+
# @example Create an application class for Admin Interface usage
|
9
|
+
# class Admin::ApplicationPaginator < Wallaby::ModelPaginator
|
10
|
+
# base_class!
|
11
|
+
# end
|
5
12
|
class ModelPaginator
|
6
13
|
extend Baseable::ClassMethods
|
7
|
-
|
8
|
-
class << self
|
9
|
-
# @!attribute [w] model_class
|
10
|
-
attr_writer :model_class
|
11
|
-
|
12
|
-
# @!attribute [r] model_class
|
13
|
-
# Return associated model class, e.g. return **Product** for **ProductPaginator**.
|
14
|
-
#
|
15
|
-
# If Wallaby can't recognise the model class for Paginator, it's required to be configured as below example:
|
16
|
-
# @example To configure model class
|
17
|
-
# class Admin::ProductPaginator < Admin::ApplicationPaginator
|
18
|
-
# self.model_class = Product
|
19
|
-
# end
|
20
|
-
# @example To configure model class for version below 5.2.0
|
21
|
-
# class Admin::ProductPaginator < Admin::ApplicationPaginator
|
22
|
-
# def self.model_class
|
23
|
-
# Product
|
24
|
-
# end
|
25
|
-
# end
|
26
|
-
# @return [Class] assoicated model class
|
27
|
-
# @return [nil] if current class is marked as base class
|
28
|
-
# @return [nil] if current class is the same as the value of {Wallaby::Configuration::Mapping#model_paginator}
|
29
|
-
# @return [nil] if current class is {Wallaby::ModelPaginator}
|
30
|
-
# @return [nil] if assoicated model class is not found
|
31
|
-
def model_class
|
32
|
-
return unless self < ModelPaginator
|
33
|
-
return if base_class? || self == Wallaby.configuration.mapping.model_paginator
|
34
|
-
|
35
|
-
@model_class ||= Map.model_class_map(name.gsub(/(^#{namespace}::)|(Paginator$)/, EMPTY_STRING))
|
36
|
-
end
|
37
|
-
|
38
|
-
# @!attribute provider_class
|
39
|
-
# @return [Class] pagination provider class
|
40
|
-
# @since 5.2.0
|
41
|
-
attr_accessor :provider_class
|
42
|
-
end
|
14
|
+
base_class!
|
43
15
|
|
44
16
|
# @!attribute [r] model_class
|
45
17
|
# @return [Class]
|
46
18
|
attr_reader :model_class
|
47
19
|
|
48
20
|
# @!attribute [r] provider
|
49
|
-
# @return [Wallaby::
|
50
|
-
# @since 5.2.0
|
21
|
+
# @return [Wallaby::ModelPaginationProvider] the instance that does the job
|
22
|
+
# @since wallaby-5.2.0
|
51
23
|
attr_reader :provider
|
52
24
|
|
53
|
-
# During initialization, Wallaby will assign a pagination provider for this paginator
|
54
|
-
# to carry out the actual execution.
|
55
|
-
#
|
56
|
-
# Therefore, all its actions can be completely replaced by user's own implemnetation.
|
57
25
|
# @param model_class [Class]
|
58
26
|
# @param collection [#to_a] a collection of the resources
|
59
27
|
# @param params [ActionController::Parameters]
|
60
28
|
def initialize(model_class, collection, params)
|
61
29
|
@model_class = self.class.model_class || model_class
|
62
|
-
raise ArgumentError,
|
30
|
+
raise ArgumentError, 'Please provide a `model_class`.' unless @model_class
|
63
31
|
|
64
32
|
@collection = collection
|
65
33
|
@params = params
|
66
34
|
@provider = Map.pagination_provider_map(@model_class).new(@collection, @params)
|
67
35
|
end
|
68
36
|
|
69
|
-
delegate(*ModelPaginationProvider.instance_methods(false), to: :provider)
|
70
37
|
# @!method paginatable?
|
71
38
|
# (see Wallaby::ModelPaginationProvider#paginatable?)
|
72
39
|
|
@@ -111,5 +78,7 @@ module Wallaby
|
|
111
78
|
|
112
79
|
# @!method number_of_pages
|
113
80
|
# (see Wallaby::ModelPaginationProvider#number_of_pages)
|
81
|
+
|
82
|
+
delegate(*ModelPaginationProvider.instance_methods(false), to: :provider)
|
114
83
|
end
|
115
84
|
end
|
@@ -53,7 +53,7 @@ module Wallaby
|
|
53
53
|
return model_class unless MODEL_ACTIONS.include? params[:action].to_sym
|
54
54
|
raise ModelNotFound, params[:resources] unless model_class
|
55
55
|
unless Map.mode_map[model_class]
|
56
|
-
raise UnprocessableEntity,
|
56
|
+
raise UnprocessableEntity, Locale.t('errors.unprocessable_entity.model', model: model_class)
|
57
57
|
end
|
58
58
|
|
59
59
|
model_class
|
@@ -1,45 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Wallaby
|
4
|
-
#
|
4
|
+
# This is the base servicer class to provider data source related operations
|
5
|
+
# for given/associated model. In general, it works together with {#authorizer}
|
6
|
+
# to ensure that all operations are legitmate.
|
7
|
+
#
|
8
|
+
# For best practice, please create an application servicer class (see example)
|
9
|
+
# to better control the functions shared between different model servicers.
|
10
|
+
# @example Create an application class for Admin Interface usage
|
11
|
+
# class Admin::ApplicationServicer < Wallaby::ModelServicer
|
12
|
+
# base_class!
|
13
|
+
# end
|
5
14
|
class ModelServicer
|
6
15
|
extend Baseable::ClassMethods
|
7
|
-
|
8
|
-
class << self
|
9
|
-
# @!attribute [w] model_class
|
10
|
-
attr_writer :model_class
|
11
|
-
|
12
|
-
# @!attribute [r] model_class
|
13
|
-
# Return associated model class, e.g. return **Product** for **ProductServicer**.
|
14
|
-
#
|
15
|
-
# If Wallaby can't recognise the model class for Servicer, it's required to be configured as below example:
|
16
|
-
# @example To configure model class
|
17
|
-
# class Admin::ProductServicer < Admin::ApplicationServicer
|
18
|
-
# self.model_class = Product
|
19
|
-
# end
|
20
|
-
# @example To configure model class for version below 5.2.0
|
21
|
-
# class Admin::ProductServicer < Admin::ApplicationServicer
|
22
|
-
# def self.model_class
|
23
|
-
# Product
|
24
|
-
# end
|
25
|
-
# end
|
26
|
-
# @return [Class] assoicated model class
|
27
|
-
# @return [nil] if current class is marked as base class
|
28
|
-
# @return [nil] if current class is the same as the value of {Wallaby::Configuration::Mapping#model_servicer}
|
29
|
-
# @return [nil] if current class is {Wallaby::ModelServicer}
|
30
|
-
# @return [nil] if assoicated model class is not found
|
31
|
-
def model_class
|
32
|
-
return unless self < ModelServicer
|
33
|
-
return if base_class? || self == Wallaby.configuration.mapping.model_servicer
|
34
|
-
|
35
|
-
@model_class ||= Map.model_class_map(name.gsub(/(^#{namespace}::)|(Servicer$)/, EMPTY_STRING))
|
36
|
-
end
|
37
|
-
|
38
|
-
# @!attribute provider_class
|
39
|
-
# @return [Class] service provider class
|
40
|
-
# @since 5.2.0
|
41
|
-
attr_accessor :provider_class
|
42
|
-
end
|
16
|
+
base_class!
|
43
17
|
|
44
18
|
# @!attribute [r] model_class
|
45
19
|
# @return [Class]
|
@@ -47,46 +21,41 @@ module Wallaby
|
|
47
21
|
|
48
22
|
# @!attribute [r] model_decorator
|
49
23
|
# @return [Wallaby::ModelDecorator]
|
50
|
-
# @since 5.2.0
|
24
|
+
# @since wallaby-5.2.0
|
51
25
|
attr_reader :model_decorator
|
52
26
|
|
53
27
|
# @!attribute [r] authorizer
|
54
28
|
# @return [Wallaby::ModelAuthorizer]
|
55
|
-
# @since 5.2.0
|
29
|
+
# @since wallaby-5.2.0
|
56
30
|
attr_reader :authorizer
|
57
31
|
|
58
32
|
# @!attribute [r] provider
|
59
|
-
# @return [Wallaby::ModelServiceProvider]
|
60
|
-
# @since 5.2.0
|
33
|
+
# @return [Wallaby::ModelServiceProvider] the instance that does the job
|
34
|
+
# @since wallaby-5.2.0
|
61
35
|
attr_reader :provider
|
62
36
|
|
63
37
|
# @!method user
|
64
38
|
# @return [Object]
|
65
|
-
# @since 5.2.0
|
39
|
+
# @since wallaby-5.2.0
|
66
40
|
delegate :user, to: :authorizer
|
67
41
|
|
68
|
-
# During initialization, Wallaby will assign a service provider for this servicer
|
69
|
-
# to carry out the actual execution.
|
70
|
-
#
|
71
|
-
# Therefore, all its actions can be completely replaced by user's own implemnetation.
|
72
42
|
# @param model_class [Class]
|
73
43
|
# @param authorizer [Wallaby::ModelAuthorizer]
|
74
44
|
# @param model_decorator [Wallaby::ModelDecorator]
|
75
|
-
# @raise [ArgumentError] if
|
45
|
+
# @raise [ArgumentError] if model_class is blank
|
76
46
|
def initialize(model_class, authorizer, model_decorator = nil)
|
77
47
|
@model_class = model_class || self.class.model_class
|
78
|
-
raise ArgumentError,
|
48
|
+
raise ArgumentError, 'Please provide a `model_class`.' unless @model_class
|
79
49
|
|
80
50
|
@model_decorator = model_decorator || Map.model_decorator_map(model_class)
|
81
51
|
@authorizer = authorizer
|
82
|
-
|
83
|
-
@provider = provider_class.new(@model_class, @model_decorator)
|
52
|
+
@provider = Map.service_provider_map(@model_class).new(@model_class, @model_decorator)
|
84
53
|
end
|
85
54
|
|
86
55
|
# @note This is a template method that can be overridden by subclasses.
|
87
56
|
# Whitelist parameters for mass assignment.
|
88
57
|
# @param params [ActionController::Parameters, Hash]
|
89
|
-
# @param action [String, Symbol]
|
58
|
+
# @param action [String, Symbol, nil]
|
90
59
|
# @return [ActionController::Parameters] permitted params
|
91
60
|
def permit(params, action = nil)
|
92
61
|
provider.permit params, action, authorizer
|
@@ -95,58 +64,59 @@ module Wallaby
|
|
95
64
|
# @note This is a template method that can be overridden by subclasses.
|
96
65
|
# Return a collection by querying the datasource (e.g. database, REST API).
|
97
66
|
# @param params [ActionController::Parameters, Hash]
|
98
|
-
# @return [Enumerable] list of
|
67
|
+
# @return [Enumerable] list of resources
|
99
68
|
def collection(params)
|
100
69
|
provider.collection params, authorizer
|
101
70
|
end
|
102
71
|
|
72
|
+
# @!method paginate(query, params)
|
103
73
|
# @note This is a template method that can be overridden by subclasses.
|
104
74
|
# Paginate given {#collection}.
|
105
75
|
# @param query [Enumerable]
|
106
76
|
# @param params [ActionController::Parameters]
|
107
|
-
# @return [Enumerable] list of
|
77
|
+
# @return [Enumerable] list of resources
|
108
78
|
delegate :paginate, to: :provider
|
109
79
|
|
110
80
|
# @note This is a template method that can be overridden by subclasses.
|
111
81
|
# Initialize an instance of the model class.
|
112
82
|
# @param params [ActionController::Parameters]
|
113
|
-
# @return [Object] initialized
|
83
|
+
# @return [Object] initialized resource
|
114
84
|
def new(params)
|
115
85
|
provider.new params, authorizer
|
116
86
|
end
|
117
87
|
|
118
88
|
# @note This is a template method that can be overridden by subclasses.
|
119
|
-
# To find a
|
89
|
+
# To find a resource.
|
120
90
|
# @param id [Object]
|
121
91
|
# @param params [ActionController::Parameters]
|
122
|
-
# @return [Object] resource
|
92
|
+
# @return [Object] found resource
|
123
93
|
def find(id, params)
|
124
94
|
provider.find id, params, authorizer
|
125
95
|
end
|
126
96
|
|
127
97
|
# @note This is a template method that can be overridden by subclasses.
|
128
|
-
# To create a
|
98
|
+
# To create a resource.
|
129
99
|
# @param resource [Object]
|
130
100
|
# @param params [ActionController::Parameters]
|
131
|
-
# @return [Object] resource
|
101
|
+
# @return [Object] created resource
|
132
102
|
def create(resource, params)
|
133
103
|
provider.create resource, params, authorizer
|
134
104
|
end
|
135
105
|
|
136
106
|
# @note This is a template method that can be overridden by subclasses.
|
137
|
-
# To update a
|
107
|
+
# To update a resource.
|
138
108
|
# @param resource [Object]
|
139
109
|
# @param params [ActionController::Parameters]
|
140
|
-
# @return [Object] resource
|
110
|
+
# @return [Object] resource
|
141
111
|
def update(resource, params)
|
142
112
|
provider.update resource, params, authorizer
|
143
113
|
end
|
144
114
|
|
145
115
|
# @note This is a template method that can be overridden by subclasses.
|
146
|
-
# To delete a
|
116
|
+
# To delete a resource.
|
147
117
|
# @param resource [Object]
|
148
118
|
# @param params [ActionController::Parameters]
|
149
|
-
# @return [Object] resource
|
119
|
+
# @return [Object] resource
|
150
120
|
def destroy(resource, params)
|
151
121
|
provider.destroy resource, params, authorizer
|
152
122
|
end
|
@@ -2,23 +2,23 @@
|
|
2
2
|
|
3
3
|
module Wallaby
|
4
4
|
class Map
|
5
|
-
#
|
6
|
-
#
|
5
|
+
# Go through each {Wallaby::Mode} (e.g. **ActiveRecord**/**Her**)
|
6
|
+
# and find out all the model classes respectively.
|
7
|
+
# Then a hash (Model => {Wallaby::Mode}) is constructed
|
8
|
+
# to tell {Wallaby} which {Wallaby::Mode} to use for a given model.
|
7
9
|
class ModeMapper
|
8
|
-
|
9
|
-
def initialize(mode_classes)
|
10
|
-
@mode_classes = mode_classes
|
11
|
-
end
|
10
|
+
extend Classifier
|
12
11
|
|
13
|
-
#
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
# @param class_names [Wallaby::ClassArray] mode class names
|
13
|
+
# @return [WallabyClassHash]
|
14
|
+
def self.execute(class_names)
|
15
|
+
ClassHash.new.tap do |hash|
|
16
|
+
next if class_names.blank?
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
class_names.each_with_object(hash) do |mode_name, map|
|
19
|
+
mode_name.model_finder.new.all.each do |model_class|
|
20
|
+
map[model_class] = mode_name
|
21
|
+
end
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -8,7 +8,7 @@ module Wallaby
|
|
8
8
|
# @param models [Array<Class>]
|
9
9
|
def initialize(configuration, models = nil)
|
10
10
|
@configuration = configuration
|
11
|
-
@models = models || []
|
11
|
+
@models = ClassArray.new(models || [])
|
12
12
|
end
|
13
13
|
|
14
14
|
# @return [Array<Class>] model class
|
@@ -26,7 +26,7 @@ module Wallaby
|
|
26
26
|
invalid_models = configured_models - @models
|
27
27
|
return if invalid_models.blank?
|
28
28
|
|
29
|
-
message =
|
29
|
+
message = Locale.t 'errors.invalid.models', models: invalid_models.to_sentence
|
30
30
|
raise InvalidError, message
|
31
31
|
end
|
32
32
|
|
@@ -2,37 +2,18 @@
|
|
2
2
|
|
3
3
|
module Wallaby
|
4
4
|
class Map
|
5
|
-
#
|
5
|
+
# Go through the class list and generate a {.map .map} that uses the class's model_class as the key.
|
6
6
|
class ModelClassMapper
|
7
|
-
# Iterate all classes and generate a hash using their model classes as the key
|
8
|
-
# @see #map
|
9
7
|
# @param class_array [Array<Class>]
|
10
|
-
# @return [
|
11
|
-
def self.map(class_array
|
12
|
-
new
|
13
|
-
|
14
|
-
|
15
|
-
protected
|
8
|
+
# @return [Wallaby::ClassHash] model class => descendant class
|
9
|
+
def self.map(class_array)
|
10
|
+
(class_array || EMPTY_ARRAY).each_with_object(ClassHash.new) do |klass, hash|
|
11
|
+
next if ModuleUtils.anonymous_class?(klass)
|
12
|
+
next if klass.try(:base_class?) || klass.model_class.blank?
|
16
13
|
|
17
|
-
|
18
|
-
def map(class_array)
|
19
|
-
(class_array || EMPTY_ARRAY).each_with_object({}) do |klass, map|
|
20
|
-
next if anonymous?(klass) || base_class?(klass) || !klass.model_class
|
21
|
-
|
22
|
-
map[klass.model_class] = block_given? ? yield(klass) : klass
|
14
|
+
hash[klass.model_class] = block_given? ? yield(klass) : klass
|
23
15
|
end
|
24
16
|
end
|
25
|
-
|
26
|
-
# @see Wallaby::ModuleUtils.anonymous_class?
|
27
|
-
def anonymous?(klass)
|
28
|
-
ModuleUtils.anonymous_class? klass
|
29
|
-
end
|
30
|
-
|
31
|
-
# @param klass [Class]
|
32
|
-
# @return [Boolean] whether the class is base or not
|
33
|
-
def base_class?(klass)
|
34
|
-
ModuleUtils.try_to klass, :base_class?
|
35
|
-
end
|
36
17
|
end
|
37
18
|
end
|
38
19
|
end
|