wallaby-core 0.2.0 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +42 -1
  3. data/app/controllers/wallaby/resources_controller.rb +15 -375
  4. data/app/security/ability.rb +1 -1
  5. data/config/locales/wallaby.en.yml +92 -128
  6. data/config/locales/wallaby_class.en.yml +2 -23
  7. data/lib/adaptors/wallaby/custom/default_provider.rb +1 -1
  8. data/lib/adaptors/wallaby/custom/model_decorator.rb +8 -7
  9. data/lib/adaptors/wallaby/custom/model_finder.rb +3 -2
  10. data/lib/adaptors/wallaby/custom/model_pagination_provider.rb +1 -1
  11. data/lib/adaptors/wallaby/custom/model_service_provider.rb +1 -40
  12. data/lib/authorizers/wallaby/cancancan_authorization_provider.rb +30 -24
  13. data/lib/authorizers/wallaby/default_authorization_provider.rb +6 -13
  14. data/lib/authorizers/wallaby/model_authorizer.rb +43 -67
  15. data/lib/authorizers/wallaby/pundit_authorization_provider.rb +21 -30
  16. data/lib/concerns/wallaby/application_concern.rb +110 -0
  17. data/lib/concerns/wallaby/authentication_concern.rb +162 -0
  18. data/lib/concerns/wallaby/authorizable.rb +8 -8
  19. data/lib/concerns/wallaby/baseable.rb +91 -10
  20. data/lib/concerns/wallaby/decoratable.rb +3 -3
  21. data/lib/concerns/wallaby/engineable.rb +1 -1
  22. data/lib/concerns/wallaby/fieldable.rb +4 -4
  23. data/lib/concerns/wallaby/paginatable.rb +3 -3
  24. data/lib/concerns/wallaby/resourcable.rb +4 -35
  25. data/lib/concerns/wallaby/resources_concern.rb +434 -0
  26. data/lib/concerns/wallaby/servicable.rb +4 -4
  27. data/lib/decorators/wallaby/resource_decorator.rb +53 -80
  28. data/lib/errors/wallaby/class_not_found.rb +6 -0
  29. data/lib/errors/wallaby/model_not_found.rb +3 -1
  30. data/lib/errors/wallaby/resource_not_found.rb +1 -1
  31. data/lib/helpers/wallaby/application_helper.rb +6 -0
  32. data/lib/helpers/wallaby/form_helper.rb +2 -3
  33. data/lib/helpers/wallaby/index_helper.rb +2 -2
  34. data/lib/helpers/wallaby/links_helper.rb +5 -5
  35. data/lib/helpers/wallaby/resources_helper.rb +3 -0
  36. data/lib/helpers/wallaby/secure_helper.rb +3 -3
  37. data/lib/helpers/wallaby/styling_helper.rb +17 -3
  38. data/lib/interfaces/wallaby/mode.rb +5 -5
  39. data/lib/interfaces/wallaby/model_authorization_provider.rb +15 -13
  40. data/lib/interfaces/wallaby/model_decorator.rb +15 -3
  41. data/lib/paginators/wallaby/model_paginator.rb +14 -45
  42. data/lib/routes/wallaby/resources_router.rb +1 -1
  43. data/lib/servicers/wallaby/model_servicer.rb +32 -62
  44. data/lib/services/wallaby/map/mode_mapper.rb +14 -14
  45. data/lib/services/wallaby/map/model_class_collector.rb +2 -2
  46. data/lib/services/wallaby/map/model_class_mapper.rb +7 -26
  47. data/lib/services/wallaby/type_renderer.rb +2 -12
  48. data/lib/utils/wallaby/locale.rb +53 -0
  49. data/lib/utils/wallaby/model_utils.rb +4 -3
  50. data/lib/utils/wallaby/module_utils.rb +1 -1
  51. data/lib/utils/wallaby/utils.rb +23 -9
  52. data/lib/wallaby/class_array.rb +75 -0
  53. data/lib/wallaby/class_hash.rb +94 -0
  54. data/lib/wallaby/classifier.rb +29 -0
  55. data/lib/wallaby/configuration/mapping.rb +33 -21
  56. data/lib/wallaby/configuration/metadata.rb +1 -1
  57. data/lib/wallaby/configuration/models.rb +5 -9
  58. data/lib/wallaby/configuration/security.rb +6 -3
  59. data/lib/wallaby/configuration/sorting.rb +1 -1
  60. data/lib/wallaby/configuration.rb +31 -2
  61. data/lib/wallaby/core/version.rb +1 -1
  62. data/lib/wallaby/core.rb +18 -6
  63. data/lib/wallaby/engine.rb +9 -20
  64. data/lib/wallaby/logger.rb +35 -0
  65. data/lib/wallaby/map.rb +20 -17
  66. data/lib/wallaby/preloader.rb +77 -0
  67. metadata +16 -9
  68. data/app/controllers/wallaby/application_controller.rb +0 -84
  69. data/app/controllers/wallaby/secure_controller.rb +0 -81
  70. data/lib/utils/wallaby/preload_utils.rb +0 -44
@@ -6,7 +6,7 @@ module Wallaby
6
6
  # Just a label
7
7
  # @return [String]
8
8
  def all_label
9
- t 'filters.all'
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
- t 'links.export', ext: 'CSV'
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: -> { t 'links.new', model: to_model_label(model_class) }
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: -> { "#{t 'links.edit'} #{decorate(resource).to_label}" }
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: -> { t 'links.delete' }
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] ||= t 'links.confirm.delete'
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 ||= -> { t 'links.cancel' }
143
+ block ||= -> { wt 'links.cancel' }
144
144
  link_to 'javascript:history.back()', html_options, &block
145
145
  end
146
146
 
@@ -3,6 +3,9 @@
3
3
  module Wallaby
4
4
  # Resources helper
5
5
  module ResourcesHelper
6
+ include ApplicationHelper
7
+ include SecureHelper
8
+
6
9
  include BaseHelper
7
10
  include FormHelper
8
11
  include IndexHelper
@@ -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 = current_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 = current_user, app = main_app)
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 = current_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 t 'labels.empty'
71
+ muted wt 'labels.empty'
58
72
  end
59
73
 
60
74
  # @return [String] grey N/A
61
75
  def na
62
- muted t 'labels.na'
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
- t("fa.v#{major}").with_indifferent_access
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, I18n.t('wallaby.mode.inherit_required', klass: klass, parent: parent_class)
64
+ raise InvalidError, Locale.t('mode.inherit_required', klass: klass, parent: parent_class)
65
65
  end
66
66
  rescue NameError => e
67
- Rails.logger.error e
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 || name.demodulize.gsub(/(Authorization)?Provider/, EMPTY_STRING).underscore
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
- # Empty initialize that accepts all sorts of args
43
- def initialize(*); end
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
- # Validate presence of a type for given field name
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 validate_presence_of(field_name, type)
165
- type || raise(::ArgumentError, I18n.t('errors.invalid.type_required', field_name: field_name))
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
- # Model paginator to provide support for pagination on index page
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::ModelServiceProvider]
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, I18n.t('errors.required', subject: 'model_class') unless @model_class
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, I18n.t('errors.unprocessable_entity.model', model: model_class)
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
- # Model servicer contains resourceful operations for Rails resourceful actions.
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 param model_class is blank
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, I18n.t('errors.required', subject: 'model_class') unless @model_class
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
- provider_class = self.class.provider_class || Map.service_provider_map(@model_class)
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 records
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 records
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 object
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 record.
89
+ # To find a resource.
120
90
  # @param id [Object]
121
91
  # @param params [ActionController::Parameters]
122
- # @return [Object] resource object
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 record.
98
+ # To create a resource.
129
99
  # @param resource [Object]
130
100
  # @param params [ActionController::Parameters]
131
- # @return [Object] resource object
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 record.
107
+ # To update a resource.
138
108
  # @param resource [Object]
139
109
  # @param params [ActionController::Parameters]
140
- # @return [Object] resource object
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 record.
116
+ # To delete a resource.
147
117
  # @param resource [Object]
148
118
  # @param params [ActionController::Parameters]
149
- # @return [Object] resource object
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
- # To generate a hash map (`model` => `mode`).
6
- # This will be used to tell if a model can be handled by Wallaby
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
- # @param mode_classes [Array<Class>] model classes
9
- def initialize(mode_classes)
10
- @mode_classes = mode_classes
11
- end
10
+ extend Classifier
12
11
 
13
- # This will walk through each mode (e.g. **ActiveRecord**/**Her**) then pull out all the models,
14
- # and then form a hash of (`model` => `mode`).
15
- # @return [Hash] { model_class => mode }
16
- def map
17
- return {} if @mode_classes.blank?
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
- @mode_classes.each_with_object({}) do |mode_class, map|
20
- mode_class.model_finder.new.all.each do |model_class|
21
- map[model_class] = mode_class
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 = I18n.t 'errors.invalid.models', models: invalid_models.to_sentence
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
- # Generate a map.
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 [Hash] model class => descendant class
11
- def self.map(class_array, &block)
12
- new.send :map, class_array, &block
13
- end
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
- # @return [Hash] model class => descendant class
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