wallaby-core 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +31 -0
  4. data/app/controllers/wallaby/application_controller.rb +84 -0
  5. data/app/controllers/wallaby/resources_controller.rb +381 -0
  6. data/app/controllers/wallaby/secure_controller.rb +81 -0
  7. data/app/security/ability.rb +13 -0
  8. data/config/locales/wallaby.en.yml +140 -0
  9. data/config/locales/wallaby_class.en.yml +30 -0
  10. data/config/routes.rb +39 -0
  11. data/lib/adaptors/wallaby/custom.rb +7 -0
  12. data/lib/adaptors/wallaby/custom/default_provider.rb +9 -0
  13. data/lib/adaptors/wallaby/custom/model_decorator.rb +71 -0
  14. data/lib/adaptors/wallaby/custom/model_finder.rb +13 -0
  15. data/lib/adaptors/wallaby/custom/model_pagination_provider.rb +14 -0
  16. data/lib/adaptors/wallaby/custom/model_service_provider.rb +48 -0
  17. data/lib/authorizers/wallaby/cancancan_authorization_provider.rb +72 -0
  18. data/lib/authorizers/wallaby/default_authorization_provider.rb +58 -0
  19. data/lib/authorizers/wallaby/model_authorizer.rb +100 -0
  20. data/lib/authorizers/wallaby/pundit_authorization_provider.rb +89 -0
  21. data/lib/concerns/wallaby/authorizable.rb +103 -0
  22. data/lib/concerns/wallaby/baseable.rb +36 -0
  23. data/lib/concerns/wallaby/decoratable.rb +101 -0
  24. data/lib/concerns/wallaby/defaultable.rb +38 -0
  25. data/lib/concerns/wallaby/engineable.rb +61 -0
  26. data/lib/concerns/wallaby/fieldable.rb +78 -0
  27. data/lib/concerns/wallaby/paginatable.rb +72 -0
  28. data/lib/concerns/wallaby/rails_overridden_methods.rb +42 -0
  29. data/lib/concerns/wallaby/resourcable.rb +149 -0
  30. data/lib/concerns/wallaby/servicable.rb +68 -0
  31. data/lib/concerns/wallaby/shared_helpers.rb +22 -0
  32. data/lib/concerns/wallaby/themeable.rb +40 -0
  33. data/lib/decorators/wallaby/resource_decorator.rb +189 -0
  34. data/lib/errors/wallaby/cell_handling.rb +6 -0
  35. data/lib/errors/wallaby/forbidden.rb +6 -0
  36. data/lib/errors/wallaby/general_error.rb +6 -0
  37. data/lib/errors/wallaby/invalid_error.rb +6 -0
  38. data/lib/errors/wallaby/model_not_found.rb +11 -0
  39. data/lib/errors/wallaby/not_authenticated.rb +6 -0
  40. data/lib/errors/wallaby/not_found.rb +6 -0
  41. data/lib/errors/wallaby/not_implemented.rb +6 -0
  42. data/lib/errors/wallaby/resource_not_found.rb +11 -0
  43. data/lib/errors/wallaby/unprocessable_entity.rb +6 -0
  44. data/lib/forms/wallaby/form_builder.rb +60 -0
  45. data/lib/helpers/wallaby/application_helper.rb +79 -0
  46. data/lib/helpers/wallaby/base_helper.rb +65 -0
  47. data/lib/helpers/wallaby/configuration_helper.rb +18 -0
  48. data/lib/helpers/wallaby/form_helper.rb +62 -0
  49. data/lib/helpers/wallaby/index_helper.rb +84 -0
  50. data/lib/helpers/wallaby/links_helper.rb +213 -0
  51. data/lib/helpers/wallaby/resources_helper.rb +52 -0
  52. data/lib/helpers/wallaby/secure_helper.rb +54 -0
  53. data/lib/helpers/wallaby/styling_helper.rb +82 -0
  54. data/lib/interfaces/wallaby/mode.rb +72 -0
  55. data/lib/interfaces/wallaby/model_authorization_provider.rb +99 -0
  56. data/lib/interfaces/wallaby/model_decorator.rb +168 -0
  57. data/lib/interfaces/wallaby/model_finder.rb +12 -0
  58. data/lib/interfaces/wallaby/model_pagination_provider.rb +107 -0
  59. data/lib/interfaces/wallaby/model_service_provider.rb +84 -0
  60. data/lib/paginators/wallaby/model_paginator.rb +115 -0
  61. data/lib/paginators/wallaby/resource_paginator.rb +12 -0
  62. data/lib/parsers/wallaby/parser.rb +34 -0
  63. data/lib/renderers/wallaby/cell.rb +137 -0
  64. data/lib/renderers/wallaby/cell_resolver.rb +89 -0
  65. data/lib/renderers/wallaby/custom_lookup_context.rb +64 -0
  66. data/lib/renderers/wallaby/custom_partial_renderer.rb +33 -0
  67. data/lib/renderers/wallaby/custom_renderer.rb +16 -0
  68. data/lib/responders/wallaby/json_api_responder.rb +101 -0
  69. data/lib/responders/wallaby/resources_responder.rb +28 -0
  70. data/lib/routes/wallaby/resources_router.rb +72 -0
  71. data/lib/servicers/wallaby/model_servicer.rb +154 -0
  72. data/lib/services/wallaby/engine_name_finder.rb +22 -0
  73. data/lib/services/wallaby/engine_url_for.rb +46 -0
  74. data/lib/services/wallaby/link_options_normalizer.rb +19 -0
  75. data/lib/services/wallaby/map/mode_mapper.rb +27 -0
  76. data/lib/services/wallaby/map/model_class_collector.rb +49 -0
  77. data/lib/services/wallaby/map/model_class_mapper.rb +38 -0
  78. data/lib/services/wallaby/prefixes_builder.rb +66 -0
  79. data/lib/services/wallaby/sorting/hash_builder.rb +19 -0
  80. data/lib/services/wallaby/sorting/link_builder.rb +69 -0
  81. data/lib/services/wallaby/sorting/next_builder.rb +63 -0
  82. data/lib/services/wallaby/sorting/single_builder.rb +20 -0
  83. data/lib/services/wallaby/type_renderer.rb +50 -0
  84. data/lib/support/action_dispatch/routing/mapper.rb +75 -0
  85. data/lib/tree/wallaby/node.rb +25 -0
  86. data/lib/utils/wallaby/cell_utils.rb +34 -0
  87. data/lib/utils/wallaby/field_utils.rb +43 -0
  88. data/lib/utils/wallaby/filter_utils.rb +20 -0
  89. data/lib/utils/wallaby/model_utils.rb +51 -0
  90. data/lib/utils/wallaby/module_utils.rb +46 -0
  91. data/lib/utils/wallaby/params_utils.rb +14 -0
  92. data/lib/utils/wallaby/preload_utils.rb +44 -0
  93. data/lib/utils/wallaby/test_utils.rb +34 -0
  94. data/lib/utils/wallaby/utils.rb +27 -0
  95. data/lib/wallaby/configuration.rb +103 -0
  96. data/lib/wallaby/configuration/features.rb +24 -0
  97. data/lib/wallaby/configuration/mapping.rb +140 -0
  98. data/lib/wallaby/configuration/metadata.rb +23 -0
  99. data/lib/wallaby/configuration/models.rb +46 -0
  100. data/lib/wallaby/configuration/pagination.rb +30 -0
  101. data/lib/wallaby/configuration/security.rb +98 -0
  102. data/lib/wallaby/configuration/sorting.rb +28 -0
  103. data/lib/wallaby/constants.rb +45 -0
  104. data/lib/wallaby/core.rb +117 -0
  105. data/lib/wallaby/core/version.rb +7 -0
  106. data/lib/wallaby/engine.rb +43 -0
  107. data/lib/wallaby/map.rb +170 -0
  108. metadata +222 -0
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wallaby
4
+ # This is the controller with only authentication logics.
5
+ class SecureController < ::Wallaby::ApplicationController
6
+ helper SecureHelper
7
+ helper_method :current_user
8
+
9
+ rescue_from NotAuthenticated, with: :unauthorized
10
+ rescue_from Forbidden, with: :forbidden
11
+
12
+ # Unauthorized page.
13
+ # @param exception [Exception] exception comes from `rescue_from`
14
+ def unauthorized(exception = nil)
15
+ error_rendering exception, __callee__
16
+ end
17
+
18
+ # Forbidden page.
19
+ # @param exception [Exception] exception comes from `rescue_from`
20
+ def forbidden(exception = nil)
21
+ error_rendering exception, __callee__
22
+ end
23
+
24
+ # @note This is a template method that can be overridden by subclasses
25
+ # This {current_user} method will try to looking up the actual implementation from the following
26
+ # places from high precedence to low:
27
+ #
28
+ # - {Wallaby::Configuration::Security#current_user}
29
+ # - `super`
30
+ # - do nothing
31
+ #
32
+ # It can be replaced completely in subclasses:
33
+ #
34
+ # ```
35
+ # def current_user
36
+ # # NOTE: please ensure `@current_user` is assigned, for instance:
37
+ # @current_user ||= User.new params.slice(:email)
38
+ # end
39
+ # ```
40
+ # @return [Object] a user object
41
+ def current_user
42
+ @current_user ||=
43
+ if security.current_user? || !defined? super
44
+ instance_exec(&security.current_user)
45
+ else
46
+ super
47
+ end
48
+ end
49
+
50
+ # @note This is a template method that can be overridden by subclasses
51
+ # This {authenticate_user!} method will try to looking up the actual implementation from the following
52
+ # places from high precedence to low:
53
+ #
54
+ # - {Wallaby::Configuration::Security#authenticate}
55
+ # - `super`
56
+ # - do nothing
57
+ #
58
+ # It can be replaced completely in subclasses:
59
+ #
60
+ # ```
61
+ # def authenticate_user!
62
+ # authenticate_or_request_with_http_basic do |username, password|
63
+ # username == 'too_simple' && password == 'too_naive'
64
+ # end
65
+ # end
66
+ # ```
67
+ # @return [true] when user is authenticated successfully
68
+ # @raise [Wallaby::NotAuthenticated] when user fails to authenticate
69
+ def authenticate_user!
70
+ authenticated =
71
+ if security.authenticate? || !defined? super
72
+ instance_exec(&security.authenticate)
73
+ else
74
+ super
75
+ end
76
+ raise NotAuthenticated unless authenticated
77
+
78
+ true
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @!visibility private
4
+ # Defualt ability for wallaby
5
+ # If main app has defined `ability.rb`, this file will not be loaded/used.
6
+ class Ability
7
+ include ::CanCan::Ability
8
+
9
+ # @param _user [Object]
10
+ def initialize(_user)
11
+ can :manage, :all
12
+ end
13
+ end
@@ -0,0 +1,140 @@
1
+ # Files in the config/locales directory are used for internationalization
2
+ # and are automatically loaded by Rails. If you want to use locales other
3
+ # than English, add the necessary files in this directory.
4
+ #
5
+ # To use the locales, use `I18n.t`:
6
+ #
7
+ # I18n.t 'hello'
8
+ #
9
+ # In views, this is aliased to just `t`:
10
+ #
11
+ # <%= t('hello') %>
12
+ #
13
+ # To use a different locale, set it with `I18n.locale`:
14
+ #
15
+ # I18n.locale = :es
16
+ #
17
+ # This would use the information in config/locales/es.yml.
18
+ #
19
+ # To learn more, please read the Rails Internationalization guide
20
+ # available at http://guides.rubyonrails.org/i18n.html.
21
+
22
+ en:
23
+ labels:
24
+ count: 'Count: '
25
+ auto_select_hint: 'Type to select...'
26
+ upload: 'Upload'
27
+ empty: 'null'
28
+ na: 'n/a'
29
+ edit: 'Edit # %{id}'
30
+ create: 'Create a %{model}'
31
+
32
+ buttons:
33
+ save: 'Save'
34
+
35
+ links:
36
+ new: 'Create %{model}'
37
+ show: 'Show'
38
+ edit: 'Edit'
39
+ delete: 'Delete'
40
+ cancel: 'Cancel'
41
+ confirm:
42
+ delete: 'Please confirm to delete'
43
+ export: 'Export as %{ext}'
44
+
45
+ http_errors:
46
+ report_error_html: 'And report the error <a href="https://github.com/reinteractive/wallaby/issues/new" target="_blank">here</a>.'
47
+ not_implemented: 'Not implemented.'
48
+ internal_server_error: 'Hope you feel better.'
49
+ bad_request: 'Your request is not supported.'
50
+ not_found: 'Not found.'
51
+ unprocessable_entity: 'Your request cannot be processed.'
52
+ unauthorized: 'You need to sign in to access this page.'
53
+ forbidden: 'You need permission to access this page.'
54
+
55
+ json_errors:
56
+ not_implemented: 'Not implemented.'
57
+ internal_server_error: 'Internal server error.'
58
+ bad_request: 'Your request is not supported.'
59
+ not_found: 'Not found.'
60
+ unprocessable_entity: 'Your request cannot be processed.'
61
+ unauthorized: 'You need to sign in to access this page.'
62
+ forbidden: 'You need permission to access this page.'
63
+
64
+ errors:
65
+ invalid:
66
+ models: '%{models} are invalid models.'
67
+ inheritance: '%{klass} does not inherit from %{parent}.'
68
+ type_required: 'Type is required for %{field_name}.'
69
+ not_found:
70
+ collection: 'Records cannot be found. Click + button to add one.'
71
+ model: 'Model %{model} cannot be found.'
72
+ resource: 'Record %{resource} cannot be found.'
73
+ unprocessable_entity:
74
+ keyword_search: 'Unable to perform keyword search when no text fields can be used.'
75
+ field_colon_search: 'Unable to perform field colon search for %{invalid_fields}.'
76
+ model: 'Unable to handle model %{model}.'
77
+ unauthorized: 'User %{user} is trying to perform %{action} on %{subject}'
78
+ pundit:
79
+ not_found:
80
+ scope_policy: 'Cannot find scope policy for %{scope}.'
81
+ attributes_for: 'Cannot find attributes for %{subject}.'
82
+ activerecord:
83
+ paginatable: '%{collection} is not paginatable.'
84
+ required: '%{subject} is required.'
85
+ not_implemented:
86
+ model_servicer: 'Custom model servicer method `%{method_name}` is not implemented'
87
+
88
+ pagination:
89
+ prev: 'Prev'
90
+ next: 'Next'
91
+ from_to: '%{from} to %{to}'
92
+ of: ' of '
93
+ total_count: '%{total}'
94
+ pers: 'Page Size'
95
+ pages: 'Page Number'
96
+
97
+ filters:
98
+ title: 'Filters'
99
+ all: 'All'
100
+
101
+ search:
102
+ hint: 'Press enter to search.'
103
+
104
+ hints:
105
+ box_html: 'Format: <code>(x1, y1), (x2, y2)</code> where <i>(x1,y1)</i> and <i>(x2,y2)</i> are any two opposite corners of the box.'
106
+ cidr_html: 'Example: <code>192.168.1.1/24</code> which holds an IPv4 or IPv6 network specification.'
107
+ circle_html: 'Format: <code><(x, y), r></code> where <i>(x,y)</i> is the center point and <i>r</i> is the radius of the circle.'
108
+ hstore_html: 'Format: <code>"Key1" => "Value1", "Key2" => "Value2"</code> is used for input and output, includes zero or more <i>key => value</i> pairs separated by commas.'
109
+ inet_html: 'Example: <code>192.168.1.1/24</code> which holds an IPv4 or IPv6 network specification.'
110
+ line_html: 'Format: <code>{ A, B, C }</code> which are represented by the linear equation <i>Ax + By + C = 0</i>.'
111
+ lseg_html: 'Format: <code>[(x1, y1), (x2, y2)]</code> where <i>(x1,y1)</i> and <i>(x2,y2)</i> are the end points of the line segment.'
112
+ ltree_html: 'Example: <code>Top.Countries.Europe.Russia</code> which is a sequence of zero or more labels separated by dots.'
113
+ macaddr_html: 'Example: <code>08:00:2b:01:02:03</code> which stores MAC addresses.'
114
+ path_html: 'Format: <code>((x1, y1) , ... , (xn, yn))</code> where the points are the end points of the line segments comprising the path.'
115
+ polygon_html: 'Format: <code>((x1, y1) , ... , (xn, yn))</code> where the points are the end points of the line segments comprising the boundary of the polygon.'
116
+
117
+ deprecation:
118
+ authorizer: "[DEPRECATION] `authorizer` will be removed from 5.3.*. Please use `current_authorizer` instead.\n(called from %{from})"
119
+ current_model_service: "[DEPRECATION] `current_model_service` will be removed from 5.3.*. Please use `current_servicer` instead.\n(called from %{from})"
120
+ find_filter_name: "[DEPRECATION] `Wallaby::Utils.find_filter_name` will be removed from 5.3.*. Please use `Wallaby::FilterUtils.filter_name_by` instead.\n(called from %{from})"
121
+ form_type_partial_render: "[DEPRECATION] `form_type_partial_render` will be removed from 5.3.*. Please use `type_render` instead.\n(called from %{from})"
122
+ index_params: "[DEPRECATION] `index_params` will be removed from 5.3.*.\n(called from %{from})"
123
+ paginator_of: "[DEPRECATION] `paginator_of` will be removed from 5.3.*. Please use `current_paginator` instead.\n(called from %{from})"
124
+ resource_paginator_inheirtance: "[DEPRECATION] `Wallaby::ResourcePaginator` will be removed from 5.3.*. Please inherit from `Wallaby::ModelPaginator` instead.\n(called from %{from})"
125
+ resource_paginator=: "[DEPRECATION] `resource_paginator=` will be removed from 5.3.*. Please use `model_paginator=` instead.\n(called from %{from})"
126
+ type_partial_render: "[DEPRECATION] `type_partial_render` will be removed from 5.3.*. Please use `type_render` instead.\n(called from %{from})"
127
+
128
+ fa:
129
+ # map fa 5's icon name to version 4
130
+ # @see this fa migration document https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4
131
+ v4:
132
+ clock: 'clock-o'
133
+ bars: 'navicon'
134
+ calendar: 'calendar-o'
135
+ check-square: 'check-square-o'
136
+ square: 'square-o'
137
+ link: 'chain'
138
+ user: 'user-o'
139
+ v5:
140
+ no-need: 'no-need'
@@ -0,0 +1,30 @@
1
+ # Files in the config/locales directory are used for internationalization
2
+ # and are automatically loaded by Rails. If you want to use locales other
3
+ # than English, add the necessary files in this directory.
4
+ #
5
+ # To use the locales, use `I18n.t`:
6
+ #
7
+ # I18n.t 'hello'
8
+ #
9
+ # In views, this is aliased to just `t`:
10
+ #
11
+ # <%= t('hello') %>
12
+ #
13
+ # To use a different locale, set it with `I18n.locale`:
14
+ #
15
+ # I18n.locale = :es
16
+ #
17
+ # This would use the information in config/locales/es.yml.
18
+ #
19
+ # To learn more, please read the Rails Internationalization guide
20
+ # available at http://guides.rubyonrails.org/i18n.html.
21
+
22
+ en:
23
+ wallaby:
24
+ map:
25
+ missing_mode_for_model_class: "[WALLABY] Don't know how to handle this model %{model}."
26
+ model_class_mapper:
27
+ missing_model_class: "[WALLABY] Please define self.model_class for %{model} or set it as global.\n @see Wallaby.configuration.mapping"
28
+
29
+ mode:
30
+ inherit_required: '%{klass} must inherit from %{parent}.'
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ Wallaby::Engine.routes.draw do
4
+ # NOTE: For health check if needed
5
+ # @see Wallaby::ApplicationController#healthy
6
+ get 'status', to: 'wallaby/resources#healthy'
7
+
8
+ with_options to: Wallaby::ResourcesRouter.new do |route|
9
+ # @see `home` action for more
10
+ route.root defaults: { action: 'home' }
11
+
12
+ # To generate error pages for all supported HTTP status
13
+ Wallaby::ERRORS.each do |status|
14
+ code = Rack::Utils::SYMBOL_TO_STATUS_CODE[status]
15
+ route.get status, defaults: { action: status }
16
+ route.get code.to_s, defaults: { action: status }
17
+ end
18
+
19
+ # To generate general CRUD resourceful routes
20
+ # @see Wallaby::ResourcesRouter
21
+ scope path: ':resources' do
22
+ # @see Wallaby::ResourcesController#index
23
+ route.get '', defaults: { action: 'index' }, as: :resources
24
+ # @see Wallaby::ResourcesController#new
25
+ route.get 'new', defaults: { action: 'new' }, as: :new_resource
26
+ # @see Wallaby::ResourcesController#edit
27
+ route.get ':id/edit', defaults: { action: 'edit' }, as: :edit_resource
28
+ # @see Wallaby::ResourcesController#show
29
+ route.get ':id', defaults: { action: 'show' }, as: :resource
30
+
31
+ # @see Wallaby::ResourcesController#create
32
+ route.post '', defaults: { action: 'create' }
33
+ # @see Wallaby::ResourcesController#update
34
+ route.match ':id', via: %i(patch put), defaults: { action: 'update' }
35
+ # @see Wallaby::ResourcesController#destroy
36
+ route.delete ':id', defaults: { action: 'destroy' }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wallaby
4
+ # Custom mode
5
+ class Custom < Mode
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wallaby
4
+ class Custom
5
+ # Default provider for custom mode
6
+ class DefaultProvider < DefaultAuthorizationProvider
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wallaby
4
+ class Custom
5
+ # Custom modal decorator
6
+ class ModelDecorator < ::Wallaby::ModelDecorator
7
+ # Assume that attributes come from the setter/getter, e.g. `name=`/`name`
8
+ # @return [ActiveSupport::HashWithIndifferentAccess] metadata
9
+ def fields
10
+ @fields ||=
11
+ ::ActiveSupport::HashWithIndifferentAccess.new.tap do |hash|
12
+ methods = model_class.public_instance_methods(false).map(&:to_s)
13
+ methods
14
+ .grep(/[^=]$/)
15
+ .select { |method_id| methods.include? "#{method_id}=" }
16
+ .each { |attribute| hash[attribute] = { label: attribute.humanize, type: 'string' } }
17
+ end.freeze
18
+ end
19
+
20
+ # A copy of {#fields} for index page
21
+ # @return [ActiveSupport::HashWithIndifferentAccess] metadata
22
+ def index_fields
23
+ @index_fields ||= Utils.clone fields
24
+ end
25
+
26
+ # A copy of {#fields} for show page
27
+ # @return [ActiveSupport::HashWithIndifferentAccess] metadata
28
+ def show_fields
29
+ @show_fields ||= Utils.clone fields
30
+ end
31
+
32
+ # A copy of {#fields} for form (new/edit) page
33
+ # @return [ActiveSupport::HashWithIndifferentAccess] metadata
34
+ def form_fields
35
+ @form_fields ||= Utils.clone fields
36
+ end
37
+
38
+ # @return [Array<String>] a list of field names for index page
39
+ def index_field_names
40
+ @index_field_names ||= reposition index_fields.keys, primary_key
41
+ end
42
+
43
+ # @return [Array<String>] a list of field names for show page
44
+ def show_field_names
45
+ @show_field_names ||= reposition show_fields.keys, primary_key
46
+ end
47
+
48
+ # @return [Array<String>] a list of field names for form (new/edit) page
49
+ def form_field_names
50
+ @form_field_names ||= form_fields.keys - [primary_key.to_s]
51
+ end
52
+
53
+ # @return [ActiveModel::Errors]
54
+ def form_active_errors(resource)
55
+ @form_active_errors ||= ActiveModel::Errors.new resource
56
+ end
57
+
58
+ # @return [String, Symbole] primary key name
59
+ def primary_key
60
+ @primary_key ||= :id
61
+ end
62
+
63
+ # @param resource [Object]
64
+ # @return [String]
65
+ def guess_title(resource)
66
+ field_name = FieldUtils.first_field_by({ name: /name|title|subject/ }, fields)
67
+ ModuleUtils.try_to resource, field_name
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wallaby
4
+ class Custom
5
+ # Model finder
6
+ class ModelFinder < ::Wallaby::ModelFinder
7
+ # @return [Array<Class>] a list of classes
8
+ def all
9
+ Wallaby.configuration.custom_models.presence
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wallaby
4
+ class Custom
5
+ # Model pagination provider
6
+ class ModelPaginationProvider < ::Wallaby::ModelPaginationProvider
7
+ # By default, it doesn't support pagination
8
+ # @return [false]
9
+ def paginatable?
10
+ false
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wallaby
4
+ class Custom
5
+ # Model service provider
6
+ class ModelServiceProvider < ::Wallaby::ModelServiceProvider
7
+ # @raise [Wallaby::NotImplemented]
8
+ def permit(*)
9
+ raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
10
+ end
11
+
12
+ # @raise [Wallaby::NotImplemented]
13
+ def collection(*)
14
+ raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
15
+ end
16
+
17
+ # @raise [Wallaby::NotImplemented]
18
+ def paginate(*)
19
+ raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
20
+ end
21
+
22
+ # @raise [Wallaby::NotImplemented]
23
+ def new(*)
24
+ raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
25
+ end
26
+
27
+ # @raise [Wallaby::NotImplemented]
28
+ def find(*)
29
+ raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
30
+ end
31
+
32
+ # @raise [Wallaby::NotImplemented]
33
+ def create(*)
34
+ raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
35
+ end
36
+
37
+ # @raise [Wallaby::NotImplemented]
38
+ def update(*)
39
+ raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
40
+ end
41
+
42
+ # @raise [Wallaby::NotImplemented]
43
+ def destroy(*)
44
+ raise Wallaby::NotImplemented, I18n.t('errors.not_implemented.model_servicer', method_name: __callee__)
45
+ end
46
+ end
47
+ end
48
+ end