wallaby-core 0.2.9 → 0.3.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/wallaby/resources_controller.rb +20 -7
- data/app/security/ability.rb +1 -1
- data/config/routes.rb +21 -14
- data/lib/adaptors/wallaby/custom/default_provider.rb +1 -1
- data/lib/adaptors/wallaby/custom/model_decorator.rb +5 -17
- data/lib/adaptors/wallaby/custom/model_finder.rb +3 -3
- data/lib/adaptors/wallaby/custom/model_pagination_provider.rb +1 -1
- data/lib/adaptors/wallaby/custom/model_service_provider.rb +1 -1
- data/lib/authorizers/wallaby/cancancan_authorization_provider.rb +12 -5
- data/lib/authorizers/wallaby/default_authorization_provider.rb +10 -1
- data/lib/authorizers/wallaby/model_authorizer.rb +41 -16
- data/lib/authorizers/wallaby/pundit_authorization_provider.rb +22 -8
- data/lib/concerns/wallaby/application_concern.rb +41 -71
- data/lib/concerns/wallaby/authentication_concern.rb +29 -127
- data/lib/concerns/wallaby/authorizable.rb +14 -57
- data/lib/concerns/wallaby/baseable.rb +24 -57
- data/lib/concerns/wallaby/configurable.rb +416 -0
- data/lib/concerns/wallaby/decoratable.rb +24 -60
- data/lib/concerns/wallaby/engineable.rb +29 -46
- data/lib/concerns/wallaby/fieldable.rb +45 -56
- data/lib/concerns/wallaby/paginatable.rb +20 -51
- data/lib/concerns/wallaby/prefixable.rb +24 -4
- data/lib/concerns/wallaby/resourcable.rb +130 -72
- data/lib/concerns/wallaby/resources_concern.rb +205 -305
- data/lib/concerns/wallaby/servicable.rb +8 -48
- data/lib/concerns/wallaby/urlable.rb +69 -0
- data/lib/decorators/wallaby/resource_decorator.rb +72 -34
- data/lib/errors/wallaby/class_not_found.rb +1 -2
- data/lib/errors/wallaby/forbidden.rb +1 -2
- data/lib/errors/wallaby/general_error.rb +1 -1
- data/lib/errors/wallaby/invalid_error.rb +1 -2
- data/lib/errors/wallaby/method_removed.rb +5 -0
- data/lib/errors/wallaby/model_not_found.rb +1 -2
- data/lib/errors/wallaby/not_authenticated.rb +1 -2
- data/lib/errors/wallaby/not_found.rb +1 -2
- data/lib/errors/wallaby/not_implemented.rb +1 -2
- data/lib/errors/wallaby/resource_not_found.rb +1 -2
- data/lib/errors/wallaby/unprocessable_entity.rb +1 -2
- data/lib/fields/wallaby/all_fields.rb +63 -0
- data/lib/forms/wallaby/form_builder.rb +2 -2
- data/lib/generators/wallaby/engine/application_generator.rb +33 -0
- data/lib/generators/wallaby/engine/authorizer/USAGE +20 -0
- data/lib/generators/wallaby/engine/authorizer/authorizer_generator.rb +19 -0
- data/lib/generators/wallaby/engine/authorizer/templates/authorizer.rb.erb +35 -0
- data/lib/generators/wallaby/engine/controller/USAGE +20 -0
- data/lib/generators/wallaby/engine/controller/controller_generator.rb +23 -0
- data/lib/generators/wallaby/engine/controller/templates/controller.rb.erb +130 -0
- data/lib/generators/wallaby/engine/decorator/USAGE +20 -0
- data/lib/generators/wallaby/engine/decorator/decorator_generator.rb +19 -0
- data/lib/generators/wallaby/engine/decorator/templates/decorator.rb.erb +5 -0
- data/lib/generators/wallaby/engine/install/USAGE +19 -0
- data/lib/generators/wallaby/engine/install/install_generator.rb +91 -0
- data/lib/generators/wallaby/engine/install/templates/application_authorizer.rb.erb +37 -0
- data/lib/generators/wallaby/engine/install/templates/application_controller.rb.erb +173 -0
- data/lib/generators/wallaby/engine/install/templates/application_decorator.rb.erb +7 -0
- data/lib/generators/wallaby/engine/install/templates/application_paginator.rb.erb +27 -0
- data/lib/generators/wallaby/engine/install/templates/application_servicer.rb.erb +47 -0
- data/lib/generators/wallaby/engine/install/templates/initializer.rb.erb +16 -0
- data/lib/generators/wallaby/engine/paginator/USAGE +20 -0
- data/lib/generators/wallaby/engine/paginator/paginator_generator.rb +19 -0
- data/lib/generators/wallaby/engine/paginator/templates/paginator.rb.erb +25 -0
- data/lib/generators/wallaby/engine/servicer/USAGE +20 -0
- data/lib/generators/wallaby/engine/servicer/servicer_generator.rb +19 -0
- data/lib/generators/wallaby/engine/servicer/templates/servicer.rb.erb +45 -0
- data/lib/helpers/wallaby/application_helper.rb +10 -59
- data/lib/helpers/wallaby/base_helper.rb +11 -11
- data/lib/helpers/wallaby/configuration_helper.rb +36 -4
- data/lib/helpers/wallaby/form_helper.rb +1 -1
- data/lib/helpers/wallaby/index_helper.rb +19 -9
- data/lib/helpers/wallaby/links_helper.rb +13 -80
- data/lib/helpers/wallaby/resources_helper.rb +39 -7
- data/lib/helpers/wallaby/secure_helper.rb +20 -19
- data/lib/interfaces/wallaby/mode.rb +8 -8
- data/lib/interfaces/wallaby/model_authorization_provider.rb +23 -22
- data/lib/interfaces/wallaby/model_decorator.rb +36 -48
- data/lib/interfaces/wallaby/model_finder.rb +3 -3
- data/lib/interfaces/wallaby/model_pagination_provider.rb +2 -6
- data/lib/interfaces/wallaby/model_service_provider.rb +4 -4
- data/lib/paginators/wallaby/model_paginator.rb +1 -1
- data/lib/responders/wallaby/json_api_responder.rb +10 -5
- data/lib/responders/wallaby/resources_responder.rb +7 -2
- data/lib/routes/wallaby/engines/base_route.rb +78 -0
- data/lib/routes/wallaby/engines/custom_app_route.rb +92 -0
- data/lib/routes/wallaby/engines/engine_route.rb +77 -0
- data/lib/routes/wallaby/resources_router.rb +100 -45
- data/lib/servicers/wallaby/model_servicer.rb +13 -13
- data/lib/services/wallaby/authorizer_finder.rb +23 -0
- data/lib/services/wallaby/class_finder.rb +42 -0
- data/lib/services/wallaby/controller_finder.rb +29 -0
- data/lib/services/wallaby/decorator_finder.rb +34 -0
- data/lib/services/wallaby/default_models_excluder.rb +45 -0
- data/lib/services/wallaby/engine_name_finder.rb +14 -11
- data/lib/services/wallaby/engine_url_for.rb +82 -37
- data/lib/services/wallaby/fields_regulator.rb +34 -0
- data/lib/services/wallaby/map/mode_mapper.rb +4 -4
- data/lib/services/wallaby/map/model_class_mapper.rb +1 -1
- data/lib/services/wallaby/model_class_filter.rb +29 -0
- data/lib/services/wallaby/paginator_finder.rb +24 -0
- data/lib/services/wallaby/prefixes_builder.rb +49 -8
- data/lib/services/wallaby/servicer_finder.rb +31 -0
- data/lib/services/wallaby/sorting/hash_builder.rb +9 -0
- data/lib/services/wallaby/sorting/link_builder.rb +7 -10
- data/lib/services/wallaby/sorting/next_builder.rb +1 -12
- data/lib/services/wallaby/sorting/single_builder.rb +1 -1
- data/lib/support/action_dispatch/routing/mapper.rb +29 -4
- data/lib/utils/wallaby/field_utils.rb +9 -8
- data/lib/utils/wallaby/inflector.rb +94 -0
- data/lib/utils/wallaby/locale.rb +2 -2
- data/lib/utils/wallaby/module_utils.rb +3 -10
- data/lib/utils/wallaby/utils.rb +21 -14
- data/lib/wallaby/class_array.rb +18 -13
- data/lib/wallaby/class_hash.rb +16 -14
- data/lib/wallaby/classifier.rb +4 -2
- data/lib/wallaby/configuration/features.rb +8 -2
- data/lib/wallaby/configuration/mapping.rb +66 -112
- data/lib/wallaby/configuration/metadata.rb +15 -12
- data/lib/wallaby/configuration/models.rb +27 -25
- data/lib/wallaby/configuration/pagination.rb +15 -19
- data/lib/wallaby/configuration/security.rb +88 -80
- data/lib/wallaby/configuration/sorting.rb +15 -17
- data/lib/wallaby/configuration.rb +58 -23
- data/lib/wallaby/constants.rb +21 -13
- data/lib/wallaby/core/version.rb +1 -1
- data/lib/wallaby/core.rb +34 -10
- data/lib/wallaby/deprecator.rb +81 -0
- data/lib/wallaby/engine.rb +1 -19
- data/lib/wallaby/guesser.rb +45 -0
- data/lib/wallaby/logger.rb +35 -13
- data/lib/wallaby/map.rb +14 -87
- data/lib/wallaby/preloader.rb +13 -25
- metadata +120 -15
- data/config/locales/wallaby_class.en.yml +0 -9
- data/lib/concerns/wallaby/defaultable.rb +0 -38
- data/lib/concerns/wallaby/shared_helpers.rb +0 -22
- data/lib/services/wallaby/map/model_class_collector.rb +0 -49
- data/lib/services/wallaby/type_renderer.rb +0 -40
- data/lib/utils/wallaby/model_utils.rb +0 -52
- data/lib/utils/wallaby/test_utils.rb +0 -34
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wallaby
|
4
|
+
module Engines
|
5
|
+
# The general route of {Engine} looks like as follow:
|
6
|
+
#
|
7
|
+
# /admin/order::items
|
8
|
+
#
|
9
|
+
# Therefore, to override this route, dev needs to define a resources as below
|
10
|
+
# before mounting {Engine}:
|
11
|
+
#
|
12
|
+
# namespace :admin do
|
13
|
+
# # NOTE: in order for the route to work properly,
|
14
|
+
# # the colon before words need to be escaped in the path option
|
15
|
+
# resources :items, path: 'order:\:item', module: :order
|
16
|
+
# end
|
17
|
+
# wallaby_mount at: '/admin'
|
18
|
+
#
|
19
|
+
# So to find out if any route has been overriden with current request, e.g. `/admin/order::items/1/edit`,
|
20
|
+
# we will look into the following conditions:
|
21
|
+
#
|
22
|
+
# - begins with `/admin`
|
23
|
+
# - same **action** as the given **action**
|
24
|
+
# - default **controller** exists (as {ResourcesRouter} does not define static **controller**)
|
25
|
+
#
|
26
|
+
# Then we use this route's params and pass it to the origin `url_for`.
|
27
|
+
class EngineRoute < BaseRoute
|
28
|
+
# A constant to map actions to its corresponding path helper methods
|
29
|
+
# defined in {Engine}'s routes.
|
30
|
+
# @see https://github.com/wallaby-rails/wallaby-core/blob/master/config/routes.rb
|
31
|
+
ACTION_TO_URL_HELPER_MAP =
|
32
|
+
Wallaby::ERRORS.each_with_object(ActiveSupport::HashWithIndifferentAccess.new) do |error, map|
|
33
|
+
map[error] = :"#{error}_path"
|
34
|
+
end.merge(
|
35
|
+
home: :root_path,
|
36
|
+
# for resourceful actions
|
37
|
+
index: :resources_path,
|
38
|
+
new: :new_resource_path,
|
39
|
+
show: :resource_path,
|
40
|
+
edit: :edit_resource_path
|
41
|
+
).freeze
|
42
|
+
|
43
|
+
def url
|
44
|
+
# NOTE: require to use `url_helper` here.
|
45
|
+
# otherwise, {Engine} will raise **ActionController::UrlGenerationError**.
|
46
|
+
engine_params = params_for(route)
|
47
|
+
Engine.routes.url_helpers.try(engine_action_url_helper, engine_params)
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
# @return [ActionDispatch::Journey::Route]
|
53
|
+
# the application route that overrides the route handled by {Engine}
|
54
|
+
def route
|
55
|
+
@route ||=
|
56
|
+
Engine.routes.routes.find do |route|
|
57
|
+
route.requirements[:action] == action_name
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [Symbol] the URL helper for given action
|
62
|
+
def engine_action_url_helper
|
63
|
+
ACTION_TO_URL_HELPER_MAP[action_name.try(:to_sym)]
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [Hash]
|
67
|
+
def complete_params
|
68
|
+
@complete_params ||=
|
69
|
+
normalize_params(
|
70
|
+
{ script_name: context.script_name },
|
71
|
+
with_query_params,
|
72
|
+
params
|
73
|
+
)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -1,68 +1,123 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Wallaby
|
4
|
-
# This is the core of
|
4
|
+
# This is the core of {Wallaby} as it dynamically dispatches request to appropriate controller and action.
|
5
|
+
#
|
6
|
+
# Assume that:
|
7
|
+
#
|
8
|
+
# - {Wallaby} is mounted at `/admin`
|
9
|
+
# - current request path is `/admin/order::items`, then the resources name is `order::items`
|
10
|
+
#
|
11
|
+
# {ResourcesRouter} will try to find out which controller to dispatch to by:
|
12
|
+
#
|
13
|
+
# - check if the controller name `Admin::Order::ItemsController` exists
|
14
|
+
# (converted from the mount path and resources name)
|
15
|
+
# - check if the `:resources_controller` defaults is set when mounting {Wallaby}, for example:
|
16
|
+
#
|
17
|
+
# ```
|
18
|
+
# wallaby_mount at: '/admin', defaults: { resources_controller: CoreController }
|
19
|
+
# ```
|
20
|
+
#
|
21
|
+
# - fall back to default resources controller from
|
22
|
+
# {Configuration#resources_controller Wallaby.configuration.resources_controller}
|
23
|
+
# @see http://edgeguides.rubyonrails.org/routing.html#routing-to-rack-applications
|
5
24
|
class ResourcesRouter
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# 1. `:resources_controller` parameter
|
11
|
-
# 2. resources_controller mapping configuration,
|
12
|
-
# e.g. `Admin::ApplicationController` if defined or `Wallaby::ResourcesController`
|
13
|
-
# @param env [Hash] @see http://www.rubydoc.info/github/rack/rack/master/file/SPEC
|
25
|
+
# It dispatches the request to corresponding controller and action.
|
26
|
+
# @param env [Hash] (see https://github.com/rack/rack/blob/master/SPEC.rdoc)
|
27
|
+
# @return [void]
|
14
28
|
def call(env)
|
15
|
-
|
16
|
-
|
17
|
-
|
29
|
+
options = get_options_from(env)
|
30
|
+
validate_model_by(options[:resources])
|
31
|
+
controller_class = find_controller_class_by(options)
|
32
|
+
controller_class.action(options[:action]).call(env)
|
18
33
|
rescue ::AbstractController::ActionNotFound, ModelNotFound => e
|
19
|
-
|
20
|
-
default_controller(
|
34
|
+
set_flash_error_for(e, env)
|
35
|
+
default_controller(options).action(:not_found).call(env)
|
21
36
|
rescue UnprocessableEntity => e
|
22
|
-
|
23
|
-
default_controller(
|
37
|
+
set_flash_error_for(e, env)
|
38
|
+
default_controller(options).action(:unprocessable_entity).call(env)
|
24
39
|
end
|
25
40
|
|
26
|
-
|
41
|
+
protected
|
27
42
|
|
28
|
-
#
|
29
|
-
# @
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
43
|
+
# @param env [Hash] (see https://github.com/rack/rack/blob/master/SPEC.rdoc)
|
44
|
+
# @return [Hash] options, which contains params and script name
|
45
|
+
def get_options_from(env)
|
46
|
+
env[ActionDispatch::Http::Parameters::PARAMETERS_KEY].merge(
|
47
|
+
script_name: env[SCRIPT_NAME]
|
48
|
+
)
|
34
49
|
end
|
35
50
|
|
36
|
-
#
|
51
|
+
# Assume that:
|
52
|
+
#
|
53
|
+
# - {Wallaby} is mounted at `/admin`
|
54
|
+
# - current request path is `/admin/order::items`, then the resources name is `order::items`
|
37
55
|
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
56
|
+
# Then it expects to return the first controller from the following list:
|
57
|
+
#
|
58
|
+
# - Admin::Order::ItemsController
|
59
|
+
# - `:resources_controller` defaults
|
60
|
+
# - default controller set by
|
61
|
+
# {Configuration#resources_controller Wallaby.configuration.resources_controller}
|
62
|
+
# @param options [Hash]
|
41
63
|
# @return [Class] controller class
|
42
|
-
def
|
43
|
-
|
44
|
-
|
64
|
+
def find_controller_class_by(options)
|
65
|
+
return default_controller(options) unless options[:resources]
|
66
|
+
|
67
|
+
Classifier.to_class(
|
68
|
+
Inflector.to_controller_name(options[:script_name], options[:resources])
|
69
|
+
) do |controller_name|
|
70
|
+
Logger.hint(
|
71
|
+
:customize_controller,
|
72
|
+
<<~INSTRUCTION
|
73
|
+
HINT: To customize the controller for resources `#{options[:resources]}`,
|
74
|
+
create the following controller:
|
45
75
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
76
|
+
class #{controller_name} < #{default_controller(options)}
|
77
|
+
def #{options[:action]}
|
78
|
+
# it's possible to re-use what's implemented by calling `#{options[:action]}!`
|
79
|
+
# or `super` if bang version does not exist
|
80
|
+
#{options[:action]}!
|
81
|
+
end
|
82
|
+
end
|
83
|
+
INSTRUCTION
|
84
|
+
)
|
85
|
+
|
86
|
+
default_controller(options)
|
57
87
|
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# @param options [Hash]
|
91
|
+
# @return [Class] default controller class
|
92
|
+
def default_controller(options)
|
93
|
+
options[:resources_controller] || Wallaby.configuration.resources_controller
|
94
|
+
end
|
95
|
+
|
96
|
+
# @param resources_name [String]
|
97
|
+
# @raise [ModelNotFound] when model class can not be not found
|
98
|
+
# @raise [UnprocessableEntity]
|
99
|
+
# when there is no corresponding {Mode} found for model class
|
100
|
+
# (which means {Wallaby})
|
101
|
+
# @return [void]
|
102
|
+
def validate_model_by(resources_name)
|
103
|
+
return unless resources_name # maybe it's for landing page or error page
|
104
|
+
|
105
|
+
# now this is for our lovely resourceful actions
|
106
|
+
model_name = Inflector.to_model_name(resources_name)
|
107
|
+
model_class = Classifier.to_class(model_name)
|
108
|
+
raise ModelNotFound, model_name unless model_class
|
109
|
+
return if Map.mode_map[model_class]
|
58
110
|
|
59
|
-
|
111
|
+
Wallaby::Logger.warn <<~MESSAGE
|
112
|
+
Cannot find the mode for #{model_name} and don't know how to handle it.
|
113
|
+
MESSAGE
|
114
|
+
raise UnprocessableEntity, Locale.t('errors.unprocessable_entity.model', model: model_class)
|
60
115
|
end
|
61
116
|
|
62
|
-
# Set flash error message
|
63
117
|
# @param exception [Exception]
|
64
|
-
# @param env [Hash]
|
65
|
-
|
118
|
+
# @param env [Hash] (see https://github.com/rack/rack/blob/master/SPEC.rdoc)
|
119
|
+
# @return [void]
|
120
|
+
def set_flash_error_for(exception, env)
|
66
121
|
session = env[ActionDispatch::Request::Session::ENV_SESSION_KEY] || {}
|
67
122
|
env[ActionDispatch::Flash::KEY] ||= ActionDispatch::Flash::FlashHash.from_session_value session['flash']
|
68
123
|
flash = env[ActionDispatch::Flash::KEY]
|
@@ -20,17 +20,17 @@ module Wallaby
|
|
20
20
|
attr_reader :model_class
|
21
21
|
|
22
22
|
# @!attribute [r] model_decorator
|
23
|
-
# @return [
|
23
|
+
# @return [ModelDecorator]
|
24
24
|
# @since wallaby-5.2.0
|
25
25
|
attr_reader :model_decorator
|
26
26
|
|
27
27
|
# @!attribute [r] authorizer
|
28
|
-
# @return [
|
28
|
+
# @return [ModelAuthorizer]
|
29
29
|
# @since wallaby-5.2.0
|
30
30
|
attr_reader :authorizer
|
31
31
|
|
32
32
|
# @!attribute [r] provider
|
33
|
-
# @return [
|
33
|
+
# @return [ModelServiceProvider] the instance that does the job
|
34
34
|
# @since wallaby-5.2.0
|
35
35
|
attr_reader :provider
|
36
36
|
|
@@ -40,21 +40,21 @@ module Wallaby
|
|
40
40
|
delegate :user, to: :authorizer
|
41
41
|
|
42
42
|
# @param model_class [Class]
|
43
|
-
# @param authorizer [
|
44
|
-
# @param model_decorator [
|
43
|
+
# @param authorizer [ModelAuthorizer]
|
44
|
+
# @param model_decorator [ModelDecorator]
|
45
45
|
# @raise [ArgumentError] if model_class is blank
|
46
|
-
def initialize(model_class, authorizer, model_decorator
|
46
|
+
def initialize(model_class, authorizer, model_decorator)
|
47
47
|
@model_class = model_class || self.class.model_class
|
48
48
|
raise ArgumentError, 'Please provide a `model_class`.' unless @model_class
|
49
49
|
|
50
|
-
@model_decorator = model_decorator
|
50
|
+
@model_decorator = model_decorator
|
51
51
|
@authorizer = authorizer
|
52
52
|
@provider = Map.service_provider_map(@model_class).new(@model_class, @model_decorator)
|
53
53
|
end
|
54
54
|
|
55
55
|
# @note This is a template method that can be overridden by subclasses.
|
56
|
-
#
|
57
|
-
# @param params [ActionController::Parameters
|
56
|
+
# Allowlist parameters for mass assignment.
|
57
|
+
# @param params [Hash, ActionController::Parameters]
|
58
58
|
# @param action [String, Symbol, nil]
|
59
59
|
# @return [ActionController::Parameters] permitted params
|
60
60
|
def permit(params, action = nil)
|
@@ -63,7 +63,7 @@ module Wallaby
|
|
63
63
|
|
64
64
|
# @note This is a template method that can be overridden by subclasses.
|
65
65
|
# Return a collection by querying the datasource (e.g. database, REST API).
|
66
|
-
# @param params [ActionController::Parameters
|
66
|
+
# @param params [Hash, ActionController::Parameters]
|
67
67
|
# @return [Enumerable] list of resources
|
68
68
|
def collection(params)
|
69
69
|
provider.collection params, authorizer
|
@@ -81,7 +81,7 @@ module Wallaby
|
|
81
81
|
# Initialize an instance of the model class.
|
82
82
|
# @param params [ActionController::Parameters]
|
83
83
|
# @return [Object] initialized resource
|
84
|
-
def new(params)
|
84
|
+
def new(params = {})
|
85
85
|
provider.new params, authorizer
|
86
86
|
end
|
87
87
|
|
@@ -90,7 +90,7 @@ module Wallaby
|
|
90
90
|
# @param id [Object]
|
91
91
|
# @param params [ActionController::Parameters]
|
92
92
|
# @return [Object] found resource
|
93
|
-
def find(id, params)
|
93
|
+
def find(id, params = {})
|
94
94
|
provider.find id, params, authorizer
|
95
95
|
end
|
96
96
|
|
@@ -117,7 +117,7 @@ module Wallaby
|
|
117
117
|
# @param resource [Object]
|
118
118
|
# @param params [ActionController::Parameters]
|
119
119
|
# @return [Object] resource
|
120
|
-
def destroy(resource, params)
|
120
|
+
def destroy(resource, params = {})
|
121
121
|
provider.destroy resource, params, authorizer
|
122
122
|
end
|
123
123
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wallaby
|
4
|
+
# (see #execute)
|
5
|
+
class AuthorizerFinder < DecoratorFinder
|
6
|
+
# Find authorizer class by script name and model class from the following places:
|
7
|
+
#
|
8
|
+
# - {#controller_class #controller_class}'s {Configurable::ClassMethods#model_authorizer #model_authorizer}
|
9
|
+
# - possible authorizer class built from script name and model class,
|
10
|
+
# e.g. **/admin** and **Order::Item** will give us the possible authorizers:
|
11
|
+
# - Admin::Order::ItemAuthorizer
|
12
|
+
# - Order::ItemAuthorizer
|
13
|
+
# - ItemAuthorizer
|
14
|
+
# - {#controller_class #controller_class}'s default
|
15
|
+
# {Configurable::ClassMethods#application_authorizer #application_authorizer}
|
16
|
+
# @return [Class] authorizer class
|
17
|
+
def execute
|
18
|
+
controller_class.model_authorizer ||
|
19
|
+
possible_default_class ||
|
20
|
+
controller_class.application_authorizer
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wallaby
|
4
|
+
# Base class to find out the class for given {#script_name}, {#model_class}, {#current_controller_class}
|
5
|
+
class ClassFinder
|
6
|
+
include ActiveModel::Model
|
7
|
+
|
8
|
+
# @!attribute script_name
|
9
|
+
# @return [String]
|
10
|
+
attr_accessor :script_name
|
11
|
+
# @!attribute model_class
|
12
|
+
# @return [Class]
|
13
|
+
attr_accessor :model_class
|
14
|
+
# @!attribute current_controller_class
|
15
|
+
# @return [Class]
|
16
|
+
attr_accessor :current_controller_class
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
# @return [Class]
|
21
|
+
def possible_default_class
|
22
|
+
Guesser.possible_class_from(possible_class_name, denamespace: denamespace?)
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [String] class name
|
26
|
+
def possible_class_name
|
27
|
+
@possible_class_name ||= Inflector.try(:"to_#{type}_name", script_name, model_class)
|
28
|
+
end
|
29
|
+
|
30
|
+
# This attribute will determine if the {#possible_default_class}
|
31
|
+
# should keep removing the namespaces one by one when looking up the class
|
32
|
+
# @return [Boolean]
|
33
|
+
def denamespace?
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [String] type for the finder
|
38
|
+
def type
|
39
|
+
self.class.name.demodulize.sub(FINDER, EMPTY_STRING).underscore
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wallaby
|
4
|
+
# (see #execute)
|
5
|
+
class ControllerFinder < ClassFinder
|
6
|
+
# Find controller class by script name and model class from the following places:
|
7
|
+
#
|
8
|
+
# - {ClassFinder#current_controller_class #current_controller_class}
|
9
|
+
# if {ClassFinder#current_controller_class #current_controller_class}'s model is the same as given
|
10
|
+
# {ClassFinder#model_class #model_class}
|
11
|
+
# - possible controller class built from script name and model class,
|
12
|
+
# e.g. **/admin** and **Order::Item** will give us the possible controller `Admin::Order::ItemsController`
|
13
|
+
# - {ClassFinder#current_controller_class #current_controller_class}'s default
|
14
|
+
# {Configurable::ClassMethods#application_controller #application_controller}
|
15
|
+
# @return [Class] controller class
|
16
|
+
def execute
|
17
|
+
return current_controller_class if model_class == current_controller_class.try(:model_class)
|
18
|
+
|
19
|
+
possible_default_class || current_controller_class.try(:application_controller)
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
# (see ClassFinder#denamespace?)
|
25
|
+
def denamespace?
|
26
|
+
false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wallaby
|
4
|
+
# (see #execute)
|
5
|
+
class DecoratorFinder < ClassFinder
|
6
|
+
# Find decorator class by script name and model class from the following places:
|
7
|
+
#
|
8
|
+
# - {#controller_class}'s {Configurable::ClassMethods#resource_decorator #resource_decorator}
|
9
|
+
# - possible decorator class built from script name and model class,
|
10
|
+
# e.g. **/admin** and **Order::Item** will give us the possible decorators:
|
11
|
+
# - Admin::Order::ItemDecorator
|
12
|
+
# - Order::ItemDecorator
|
13
|
+
# - ItemDecorator
|
14
|
+
# - {#controller_class}'s default
|
15
|
+
# {Configurable::ClassMethods#application_decorator #application_decorator}
|
16
|
+
# @return [Class] decorator class
|
17
|
+
def execute
|
18
|
+
controller_class.resource_decorator ||
|
19
|
+
possible_default_class ||
|
20
|
+
controller_class.application_decorator
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
# (see ControllerFinder#execute)
|
26
|
+
def controller_class
|
27
|
+
@controller_class ||= ControllerFinder.new(
|
28
|
+
script_name: script_name,
|
29
|
+
model_class: model_class,
|
30
|
+
current_controller_class: current_controller_class
|
31
|
+
).execute
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wallaby
|
4
|
+
# see {.execute}
|
5
|
+
class DefaultModelsExcluder
|
6
|
+
class << self
|
7
|
+
# {Wallaby} excludes the following model classes by default.
|
8
|
+
#
|
9
|
+
# - ActiveRecord::SchemaMigration
|
10
|
+
# - ActiveRecord::InternalMetadata
|
11
|
+
# @return [ClassArray] a list of model classes
|
12
|
+
def execute
|
13
|
+
ClassArray.new(
|
14
|
+
[].tap do |list|
|
15
|
+
list << active_record_schema_migration_class
|
16
|
+
list << active_record_internal_metadata_class
|
17
|
+
end.compact
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# @return [Class] if Wallaby knows about `ActiveRecord::SchemaMigration`
|
24
|
+
# @return [nil] otherwise
|
25
|
+
def active_record_schema_migration_class
|
26
|
+
exists =
|
27
|
+
defined?(::ActiveRecord::SchemaMigration) \
|
28
|
+
&& Map.mode_map.key?(::ActiveRecord::SchemaMigration)
|
29
|
+
|
30
|
+
exists ? ::ActiveRecord::SchemaMigration : nil
|
31
|
+
end
|
32
|
+
|
33
|
+
# NOTE: `ActiveRecord::InternalMetadata` exists since Rails 6.0
|
34
|
+
# @return [Class] if Wallaby knows about `ActiveRecord::InternalMetadata`
|
35
|
+
# @return [nil] otherwise
|
36
|
+
def active_record_internal_metadata_class
|
37
|
+
exists =
|
38
|
+
defined?(::ActiveRecord::InternalMetadata) \
|
39
|
+
&& Map.mode_map.key?(::ActiveRecord::InternalMetadata)
|
40
|
+
|
41
|
+
exists ? ::ActiveRecord::InternalMetadata : nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,21 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Wallaby
|
4
|
-
#
|
4
|
+
# Find out the engine routing proxy name
|
5
5
|
class EngineNameFinder
|
6
6
|
class << self
|
7
|
-
#
|
7
|
+
# Go through all the routes and find out the engine routing proxy name
|
8
|
+
# for the given request path.
|
8
9
|
#
|
9
|
-
# When it can't find the engine name, it will return empty string
|
10
|
-
#
|
11
|
-
# @
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
# When it can't find the engine name, it will return empty string
|
11
|
+
# to prevent it from being run again.
|
12
|
+
# @param request_path [String] request path
|
13
|
+
# @return [String] engine name if found
|
14
|
+
# @return [String] empty string "" if not found
|
15
|
+
def execute(request_path)
|
16
|
+
named_routes =
|
17
|
+
Rails.application.routes.routes.find do |route|
|
18
|
+
route.path.match(request_path) && route.app.app == Wallaby::Engine
|
19
|
+
end
|
16
20
|
|
17
|
-
|
18
|
-
named_route.try(:name) || EMPTY_STRING
|
21
|
+
named_routes.try(:name) || EMPTY_STRING
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|