strongbolt 0.3.12 → 0.3.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +56 -0
- data/.rubocop_todo.yml +91 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +18 -2
- data/Rakefile +1 -1
- data/app/controllers/strongbolt/capabilities_controller.rb +36 -45
- data/app/controllers/strongbolt/roles_controller.rb +39 -47
- data/app/controllers/strongbolt/security_controller.rb +2 -3
- data/app/controllers/strongbolt/user_groups_controller.rb +48 -54
- data/app/controllers/strongbolt/user_groups_users_controller.rb +2 -4
- data/app/controllers/strongbolt_controller.rb +1 -1
- data/circle.yml +13 -0
- data/lib/generators/strongbolt/fix_generator.rb +5 -6
- data/lib/generators/strongbolt/fix_unique_group_members_generator.rb +2 -3
- data/lib/generators/strongbolt/indexes_generator.rb +3 -4
- data/lib/generators/strongbolt/install_generator.rb +8 -9
- data/lib/generators/strongbolt/templates/fix_unique_group_members.rb +1 -1
- data/lib/generators/strongbolt/templates/indexes.rb +1 -1
- data/lib/generators/strongbolt/templates/migration.rb +11 -12
- data/lib/generators/strongbolt/templates/strongbolt.rb +1 -1
- data/lib/generators/strongbolt/views_generator.rb +4 -4
- data/lib/strongbolt.rb +51 -54
- data/lib/strongbolt/base.rb +1 -1
- data/lib/strongbolt/bolted.rb +12 -13
- data/lib/strongbolt/bolted_controller.rb +46 -57
- data/lib/strongbolt/capabilities_role.rb +5 -5
- data/lib/strongbolt/capability.rb +32 -31
- data/lib/strongbolt/configuration.rb +18 -19
- data/lib/strongbolt/controllers/url_helpers.rb +5 -5
- data/lib/strongbolt/engine.rb +9 -9
- data/lib/strongbolt/errors.rb +4 -4
- data/lib/strongbolt/generators/migration.rb +4 -6
- data/lib/strongbolt/helpers.rb +5 -7
- data/lib/strongbolt/rails/routes.rb +4 -4
- data/lib/strongbolt/role.rb +11 -12
- data/lib/strongbolt/roles_user_group.rb +5 -5
- data/lib/strongbolt/rspec.rb +2 -2
- data/lib/strongbolt/rspec/user.rb +13 -15
- data/lib/strongbolt/tenantable.rb +78 -80
- data/lib/strongbolt/user_abilities.rb +44 -54
- data/lib/strongbolt/user_group.rb +8 -10
- data/lib/strongbolt/user_groups_user.rb +6 -6
- data/lib/strongbolt/version.rb +1 -1
- data/lib/tasks/strongbolt_tasks.rake +4 -4
- data/spec/controllers/strongbolt/capabilities_controller_spec.rb +28 -45
- data/spec/controllers/strongbolt/roles_controller_spec.rb +39 -72
- data/spec/controllers/strongbolt/user_groups_controller_spec.rb +34 -65
- data/spec/controllers/strongbolt/user_groups_users_controller_spec.rb +11 -19
- data/spec/controllers/without_authorization_controller_spec.rb +5 -5
- data/spec/dummy/app/controllers/posts_controller.rb +2 -2
- data/spec/dummy/app/controllers/test_controller.rb +1 -1
- data/spec/dummy/app/controllers/without_authorization_controller.rb +1 -1
- data/spec/dummy/bin/rails +1 -1
- data/spec/dummy/config.ru +1 -1
- data/spec/dummy/config/application.rb +4 -5
- data/spec/dummy/config/initializers/cookies_serializer.rb +1 -1
- data/spec/dummy/config/initializers/strongbolt.rb +2 -2
- data/spec/dummy/config/routes.rb +1 -3
- data/spec/dummy/db/migrate/20150630212236_create_strongbolt_tables.rb +9 -10
- data/spec/dummy/db/migrate/20150630212251_create_strongbolt_tables_indexes.rb +2 -2
- data/spec/dummy/db/migrate/20160531110509_fix_unique_group_members.rb +1 -1
- data/spec/fabricators/capability_fabricator.rb +4 -4
- data/spec/fabricators/role_fabricator.rb +3 -3
- data/spec/fabricators/user_fabricator.rb +2 -2
- data/spec/fabricators/user_group_fabricator.rb +3 -3
- data/spec/fixtures/application.rb +6 -3
- data/spec/fixtures/controllers.rb +1 -1
- data/spec/spec_helper.rb +7 -8
- data/spec/strongbolt/bolted_controller_spec.rb +110 -208
- data/spec/strongbolt/bolted_spec.rb +26 -40
- data/spec/strongbolt/capability_spec.rb +72 -86
- data/spec/strongbolt/configuration_spec.rb +33 -46
- data/spec/strongbolt/controllers/url_helpers_spec.rb +7 -9
- data/spec/strongbolt/helpers_spec.rb +14 -16
- data/spec/strongbolt/role_spec.rb +32 -35
- data/spec/strongbolt/tenantable_spec.rb +88 -86
- data/spec/strongbolt/user_abilities_multiple_tenants_spec.rb +29 -34
- data/spec/strongbolt/user_abilities_spec.rb +142 -188
- data/spec/strongbolt/user_group_spec.rb +14 -14
- data/spec/strongbolt/users_tenant_spec.rb +10 -12
- data/spec/strongbolt_spec.rb +53 -73
- data/spec/support/controller_macros.rb +1 -3
- data/spec/support/db_setup.rb +31 -25
- data/spec/support/helpers.rb +12 -12
- data/spec/support/transactional_specs.rb +1 -3
- data/strongbolt.gemspec +14 -12
- metadata +20 -3
data/lib/strongbolt/base.rb
CHANGED
data/lib/strongbolt/bolted.rb
CHANGED
@@ -21,7 +21,7 @@ module Strongbolt
|
|
21
21
|
#
|
22
22
|
def unbolted?
|
23
23
|
Grant::Status.grant_disabled? || (defined?(Rails) && defined?(Rails.console)) ||
|
24
|
-
|
24
|
+
Strongbolt.current_user.nil?
|
25
25
|
end
|
26
26
|
|
27
27
|
#
|
@@ -39,16 +39,16 @@ module Strongbolt
|
|
39
39
|
return unless owned?
|
40
40
|
|
41
41
|
@owner_attribute ||= if self <= Configuration.user_class.constantize
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
:id
|
43
|
+
else
|
44
|
+
owner_association.foreign_key.to_sym
|
45
|
+
end
|
46
46
|
end
|
47
47
|
|
48
48
|
#
|
49
49
|
# Authorize as another model
|
50
50
|
#
|
51
|
-
def authorize_as
|
51
|
+
def authorize_as(model_name)
|
52
52
|
@name_for_authorization = model_name
|
53
53
|
end
|
54
54
|
|
@@ -66,14 +66,13 @@ module Strongbolt
|
|
66
66
|
#
|
67
67
|
def owner_association
|
68
68
|
@owner_association ||= reflect_on_all_associations(:belongs_to).select do |assoc|
|
69
|
-
|
70
|
-
assoc.klass <= Configuration.user_class.constantize
|
71
|
-
else
|
69
|
+
if assoc.options.key? :polymorphic
|
72
70
|
false
|
71
|
+
else
|
72
|
+
assoc.klass <= Configuration.user_class.constantize
|
73
73
|
end
|
74
74
|
end.try(:first)
|
75
75
|
end
|
76
|
-
|
77
76
|
end
|
78
77
|
|
79
78
|
module InstanceMethods
|
@@ -102,7 +101,6 @@ module Strongbolt
|
|
102
101
|
|
103
102
|
# We add the grant to filter everything
|
104
103
|
receiver.class_eval do
|
105
|
-
|
106
104
|
#
|
107
105
|
# We use the grant helper method to test authorizations on all methods
|
108
106
|
#
|
@@ -111,16 +109,17 @@ module Strongbolt
|
|
111
109
|
# Check the user permission unless no user or rails console
|
112
110
|
# Not using unbolted? here
|
113
111
|
granted = ((defined?(Rails) && defined?(Rails.console)) || user.nil?) ||
|
114
|
-
|
112
|
+
user.can?(action, instance)
|
115
113
|
|
116
114
|
# If not granted, trigger the access denied
|
117
115
|
unless granted
|
116
|
+
# rubocop:disable Style/GlobalVars
|
118
117
|
Strongbolt.access_denied user, instance, action, $request.try(:fullpath)
|
118
|
+
# rubocop:enable Style/GlobalVars
|
119
119
|
end
|
120
120
|
|
121
121
|
granted
|
122
122
|
end # End Grant
|
123
|
-
|
124
123
|
end
|
125
124
|
end
|
126
125
|
end
|
@@ -1,32 +1,31 @@
|
|
1
1
|
module Strongbolt
|
2
2
|
module BoltedController
|
3
|
-
|
4
3
|
#
|
5
4
|
# Maps controller actions to CRUD operations
|
6
5
|
#
|
7
6
|
ACTIONS_MAPPING = {
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
}
|
7
|
+
index: :find,
|
8
|
+
show: :find,
|
9
|
+
edit: :update,
|
10
|
+
update: :update,
|
11
|
+
new: :create,
|
12
|
+
create: :create,
|
13
|
+
destroy: :destroy
|
14
|
+
}.freeze
|
16
15
|
|
17
16
|
module ClassMethods
|
18
17
|
#
|
19
18
|
# Allows defining a specific model for this controller,
|
20
19
|
# if it cannot be infer from the controller name
|
21
20
|
#
|
22
|
-
def model_for_authorization=
|
21
|
+
def model_for_authorization=(model)
|
23
22
|
@model_for_authorization = case model
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
when Class then model
|
24
|
+
when String then constantize_model(model)
|
25
|
+
when nil then nil
|
26
|
+
else
|
27
|
+
raise ArgumentError, 'Model for authorization must be a Class or the name of the Class'
|
28
|
+
end
|
30
29
|
end
|
31
30
|
|
32
31
|
#
|
@@ -40,14 +39,14 @@ module Strongbolt
|
|
40
39
|
# We cannot just do controller_name.classify as it doesn't keep the modules
|
41
40
|
# We'll also check demoduling one module after the other for case when
|
42
41
|
# the controller and/or the model have different modules
|
43
|
-
full_name = name.sub(
|
42
|
+
full_name = name.sub('Controller', '').classify
|
44
43
|
# Split by ::
|
45
44
|
splits = full_name.split('::')
|
46
45
|
# While we still have modules to test
|
47
46
|
while splits.size >= 1
|
48
47
|
begin
|
49
48
|
return constantize_model splits.join('::')
|
50
|
-
rescue Strongbolt::ModelNotFound
|
49
|
+
rescue Strongbolt::ModelNotFound
|
51
50
|
ensure
|
52
51
|
# Removes first element
|
53
52
|
splits.shift
|
@@ -62,10 +61,8 @@ module Strongbolt
|
|
62
61
|
# No argument given will skip for all actions,
|
63
62
|
# and can be passed only: [] or except: []
|
64
63
|
#
|
65
|
-
def skip_controller_authorization
|
66
|
-
if Rails::VERSION::MAJOR >= 5
|
67
|
-
opts = { raise: false }.merge(opts)
|
68
|
-
end
|
64
|
+
def skip_controller_authorization(opts = {})
|
65
|
+
opts = { raise: false }.merge(opts) if Rails::VERSION::MAJOR >= 5
|
69
66
|
skip_before_action :check_authorization, opts
|
70
67
|
end
|
71
68
|
|
@@ -73,7 +70,7 @@ module Strongbolt
|
|
73
70
|
# Skip all authorization checking for the controller,
|
74
71
|
# or a subset of actions
|
75
72
|
#
|
76
|
-
def skip_all_authorization
|
73
|
+
def skip_all_authorization(opts = {})
|
77
74
|
skip_controller_authorization opts
|
78
75
|
around_action :disable_authorization, opts
|
79
76
|
end
|
@@ -81,7 +78,7 @@ module Strongbolt
|
|
81
78
|
#
|
82
79
|
# Sets what CRUD operation match a specific sets of non RESTful actions
|
83
80
|
#
|
84
|
-
[
|
81
|
+
%i[find update create destroy].each do |operation|
|
85
82
|
define_method "authorize_as_#{operation}" do |*args|
|
86
83
|
args.each do |action|
|
87
84
|
actions_mapping[action] = operation
|
@@ -92,7 +89,7 @@ module Strongbolt
|
|
92
89
|
#
|
93
90
|
# Render without authorization, for better performance
|
94
91
|
#
|
95
|
-
def render_without_authorization
|
92
|
+
def render_without_authorization(*actions)
|
96
93
|
self.actions_without_authorization = [*actions]
|
97
94
|
|
98
95
|
class_eval do
|
@@ -100,11 +97,11 @@ module Strongbolt
|
|
100
97
|
# It needs to be created afterward,
|
101
98
|
# No idea why
|
102
99
|
#
|
103
|
-
def render
|
100
|
+
def render(*args)
|
104
101
|
if render_without_authorization?
|
105
|
-
Strongbolt.without_authorization { _render
|
102
|
+
Strongbolt.without_authorization { _render(*args) }
|
106
103
|
else
|
107
|
-
_render
|
104
|
+
_render(*args)
|
108
105
|
end
|
109
106
|
end
|
110
107
|
end
|
@@ -130,24 +127,20 @@ module Strongbolt
|
|
130
127
|
#
|
131
128
|
# Try to constantize a class
|
132
129
|
#
|
133
|
-
def constantize_model
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
raise Strongbolt::ModelNotFound, "Model for controller #{controller_name} wasn't found"
|
138
|
-
end
|
130
|
+
def constantize_model(name)
|
131
|
+
name.constantize
|
132
|
+
rescue NameError
|
133
|
+
raise Strongbolt::ModelNotFound, "Model for controller #{controller_name} wasn't found"
|
139
134
|
end
|
140
|
-
|
141
135
|
end
|
142
136
|
|
143
137
|
module InstanceMethods
|
144
|
-
|
145
|
-
|
146
|
-
Strongbolt.current_user.can? *args
|
138
|
+
def can?(*args)
|
139
|
+
Strongbolt.current_user.can?(*args)
|
147
140
|
end
|
148
141
|
|
149
|
-
def cannot?
|
150
|
-
Strongbolt.current_user.cannot?
|
142
|
+
def cannot?(*args)
|
143
|
+
Strongbolt.current_user.cannot?(*args)
|
151
144
|
end
|
152
145
|
|
153
146
|
#
|
@@ -163,11 +156,11 @@ module Strongbolt
|
|
163
156
|
#
|
164
157
|
# DOESN'T WORK WHEN DEFINED HERE?
|
165
158
|
#
|
166
|
-
def render
|
159
|
+
def render(*args)
|
167
160
|
if render_without_authorization?
|
168
|
-
Strongbolt.without_authorization { _render
|
161
|
+
Strongbolt.without_authorization { _render(*args) }
|
169
162
|
else
|
170
|
-
_render
|
163
|
+
_render(*args)
|
171
164
|
end
|
172
165
|
end
|
173
166
|
|
@@ -183,7 +176,9 @@ module Strongbolt
|
|
183
176
|
#
|
184
177
|
def set_current_user
|
185
178
|
# To be accessible in the model when not granted
|
179
|
+
# rubocop:disable Style/GlobalVars
|
186
180
|
$request = request
|
181
|
+
# rubocop:enable Style/GlobalVars
|
187
182
|
Grant::Status.without_grant do
|
188
183
|
Strongbolt.current_user = send(:current_user) if respond_to?(:current_user)
|
189
184
|
end
|
@@ -207,7 +202,7 @@ module Strongbolt
|
|
207
202
|
begin
|
208
203
|
# Current model
|
209
204
|
# begin
|
210
|
-
|
205
|
+
obj = self.class.model_for_authorization
|
211
206
|
# rescue Strongbolt::ModelNotFound
|
212
207
|
# Strongbolt.logger.warn "No class found or defined for controller #{controller_name}"
|
213
208
|
# return
|
@@ -224,7 +219,7 @@ module Strongbolt
|
|
224
219
|
raise e
|
225
220
|
end
|
226
221
|
else
|
227
|
-
Strongbolt.logger.warn
|
222
|
+
Strongbolt.logger.warn 'No authorization checking because no current user'
|
228
223
|
end
|
229
224
|
end
|
230
225
|
|
@@ -232,17 +227,15 @@ module Strongbolt
|
|
232
227
|
# Catch Grant::Error and send Strongbolt::Unauthorized instead
|
233
228
|
#
|
234
229
|
def catch_grant_error
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
raise Strongbolt::Unauthorized, e.to_s
|
239
|
-
end
|
230
|
+
yield
|
231
|
+
rescue Grant::Error => e
|
232
|
+
raise Strongbolt::Unauthorized, e.to_s
|
240
233
|
end
|
241
234
|
|
242
235
|
#
|
243
236
|
# Returns the CRUD operations based on the action name
|
244
237
|
#
|
245
|
-
def crud_operation_of
|
238
|
+
def crud_operation_of(action)
|
246
239
|
operation = self.class.actions_mapping[action.to_sym]
|
247
240
|
# If nothing find, we raise an error
|
248
241
|
if operation.nil?
|
@@ -257,9 +250,8 @@ module Strongbolt
|
|
257
250
|
#
|
258
251
|
def disable_authorization
|
259
252
|
Strongbolt.without_authorization { yield }
|
260
|
-
Strongbolt.logger.warn
|
253
|
+
Strongbolt.logger.warn 'Authorization were disabled!'
|
261
254
|
end
|
262
|
-
|
263
255
|
end
|
264
256
|
|
265
257
|
def self.included(receiver)
|
@@ -285,16 +277,13 @@ module Strongbolt
|
|
285
277
|
if respond_to? :unauthorized
|
286
278
|
unauthorized e
|
287
279
|
else
|
288
|
-
raise Strongbolt::Unauthorized
|
280
|
+
raise Strongbolt::Unauthorized, e.to_s
|
289
281
|
end
|
290
282
|
end
|
291
|
-
|
292
283
|
end # End receiver class eval
|
293
284
|
|
294
285
|
receiver.extend ClassMethods
|
295
286
|
receiver.send :include, InstanceMethods
|
296
|
-
|
297
287
|
end # End self.included
|
298
|
-
|
299
288
|
end
|
300
289
|
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module Strongbolt
|
2
2
|
class CapabilitiesRole < Base
|
3
|
-
authorize_as
|
3
|
+
authorize_as 'Strongbolt::Role'
|
4
4
|
|
5
5
|
belongs_to :role,
|
6
|
-
|
7
|
-
|
6
|
+
class_name: 'Strongbolt::Role',
|
7
|
+
inverse_of: :capabilities_roles
|
8
8
|
|
9
9
|
belongs_to :capability,
|
10
|
-
|
11
|
-
|
10
|
+
class_name: 'Strongbolt::Capability',
|
11
|
+
inverse_of: :capabilities_roles
|
12
12
|
|
13
13
|
validates_presence_of :role, :capability
|
14
14
|
end
|
@@ -1,25 +1,24 @@
|
|
1
1
|
module Strongbolt
|
2
2
|
class Capability < Base
|
3
|
+
Actions = %w[find create update destroy].freeze
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
"Strongbolt::Capability",
|
9
|
-
"Strongbolt::UsersTenant"]
|
5
|
+
DEFAULT_MODELS = ['Strongbolt::UserGroup',
|
6
|
+
'Strongbolt::Role',
|
7
|
+
'Strongbolt::Capability',
|
8
|
+
'Strongbolt::UsersTenant'].freeze
|
10
9
|
|
11
10
|
has_many :capabilities_roles,
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
class_name: 'Strongbolt::CapabilitiesRole',
|
12
|
+
dependent: :restrict_with_exception,
|
13
|
+
inverse_of: :capability
|
15
14
|
|
16
|
-
has_many :roles, :
|
15
|
+
has_many :roles, through: :capabilities_roles
|
17
16
|
|
18
17
|
has_many :users, through: :roles
|
19
18
|
|
20
19
|
validates :model, :action, presence: true
|
21
20
|
validates :action, inclusion: Actions,
|
22
|
-
|
21
|
+
uniqueness: { scope: %i[model require_ownership require_tenant_access] }
|
23
22
|
validate :model_exists?
|
24
23
|
|
25
24
|
before_validation :set_default
|
@@ -28,10 +27,15 @@ module Strongbolt
|
|
28
27
|
#
|
29
28
|
# List all the models to be used in capabilities
|
30
29
|
#
|
31
|
-
def self.models
|
32
|
-
|
30
|
+
def self.models
|
31
|
+
@models ||= DEFAULT_MODELS
|
32
|
+
end
|
33
|
+
|
34
|
+
class << self
|
35
|
+
attr_writer :models
|
36
|
+
end
|
33
37
|
|
34
|
-
def self.add_models
|
38
|
+
def self.add_models(models)
|
35
39
|
@models ||= DEFAULT_MODELS
|
36
40
|
@models |= [*models]
|
37
41
|
@models.sort!
|
@@ -39,9 +43,9 @@ module Strongbolt
|
|
39
43
|
|
40
44
|
scope :ordered, -> {
|
41
45
|
select("#{self.table_name}.*")
|
42
|
-
.select("CASE WHEN action = 'find' THEN 0 "
|
43
|
-
"WHEN action = 'create' THEN 1 "
|
44
|
-
"WHEN action = 'update' THEN 2 "
|
46
|
+
.select("CASE WHEN action = 'find' THEN 0 " \
|
47
|
+
"WHEN action = 'create' THEN 1 " \
|
48
|
+
"WHEN action = 'update' THEN 2 " \
|
45
49
|
"WHEN action = 'destroy' THEN 3 END AS action_id")
|
46
50
|
.order(:model, :require_ownership, :require_tenant_access, 'action_id')
|
47
51
|
}
|
@@ -54,9 +58,9 @@ module Strongbolt
|
|
54
58
|
table = []
|
55
59
|
all.ordered.each do |capability|
|
56
60
|
if table.last.nil? ||
|
57
|
-
|
58
|
-
|
59
|
-
|
61
|
+
!(table.last[:model] == capability.model &&
|
62
|
+
table.last[:require_ownership] == capability.require_ownership &&
|
63
|
+
table.last[:require_tenant_access] == capability.require_tenant_access)
|
60
64
|
|
61
65
|
table << {
|
62
66
|
model: capability.model,
|
@@ -98,11 +102,8 @@ module Strongbolt
|
|
98
102
|
hash[key][capability.action.to_sym] = true
|
99
103
|
end
|
100
104
|
hash
|
101
|
-
end
|
102
|
-
|
105
|
+
end #
|
103
106
|
|
104
|
-
|
105
|
-
#
|
106
107
|
# Create a set capabilities from a hash
|
107
108
|
# which has:
|
108
109
|
# {
|
@@ -114,20 +115,20 @@ module Strongbolt
|
|
114
115
|
# Actions can be either one operation, an array of operations,
|
115
116
|
# or :all meaning all operations
|
116
117
|
#
|
117
|
-
def self.from_hash
|
118
|
+
def self.from_hash(hash)
|
118
119
|
hash.symbolize_keys!
|
119
120
|
actions_from_list(hash[:actions]).map do |action|
|
120
|
-
new :
|
121
|
-
|
122
|
-
|
123
|
-
|
121
|
+
new model: hash[:model],
|
122
|
+
require_ownership: hash[:require_ownership],
|
123
|
+
require_tenant_access: hash[:require_tenant_access],
|
124
|
+
action: action
|
124
125
|
end
|
125
126
|
end
|
126
127
|
|
127
128
|
#
|
128
129
|
# Virtual setter of actions
|
129
130
|
#
|
130
|
-
def self.actions_from_list
|
131
|
+
def self.actions_from_list(actions)
|
131
132
|
# Transform actions array
|
132
133
|
if actions.respond_to?(:to_sym) && actions.to_sym == :all
|
133
134
|
Actions # All actions
|
@@ -145,7 +146,7 @@ module Strongbolt
|
|
145
146
|
if model.present?
|
146
147
|
begin
|
147
148
|
model.constantize
|
148
|
-
rescue NameError
|
149
|
+
rescue NameError
|
149
150
|
errors.add :model, "#{model} is not a valid model"
|
150
151
|
end
|
151
152
|
end
|