wallaby-core 0.2.0 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|