params_checker 0.2.2 → 0.2.3
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.
- checksums.yaml +4 -4
- data/README.md +1168 -5
- data/lib/params_checker/base_params_checker.rb +186 -161
- data/lib/params_checker/constants.rb +45 -0
- data/lib/params_checker/engine.rb +4 -0
- data/lib/params_checker/field_error.rb +11 -0
- data/lib/params_checker/fields.rb +242 -160
- data/lib/params_checker/{my_error.rb → general_error.rb} +2 -2
- data/lib/params_checker/helper.rb +21 -0
- data/lib/params_checker/param_checker.rb +312 -298
- data/lib/params_checker/version.rb +1 -1
- data/lib/params_checker.rb +9 -7
- metadata +19 -10
- data/app/assets/config/params_checker_manifest.js +0 -1
- data/app/assets/stylesheets/params_checker/application.css +0 -15
- data/app/controllers/params_checker/application_controller.rb +0 -5
- data/app/helpers/params_checker/application_helper.rb +0 -4
- data/app/jobs/params_checker/application_job.rb +0 -4
- data/app/mailers/params_checker/application_mailer.rb +0 -6
- data/app/models/params_checker/application_record.rb +0 -5
- data/app/views/layouts/params_checker/application.html.erb +0 -15
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
DEFAULT_MESSAGE_ERROR = 'Fields are not valid'
|
4
|
+
ERROR_TYPES = %w[general_error field_errors]
|
1
5
|
module ParamsChecker
|
2
6
|
class BaseParamsChecker
|
3
7
|
include Fields
|
@@ -6,244 +10,265 @@ module ParamsChecker
|
|
6
10
|
@params = params
|
7
11
|
@context = context
|
8
12
|
@is_outest_hash = is_outest_hash
|
9
|
-
@
|
10
|
-
@
|
11
|
-
@
|
13
|
+
@formatted_params_after_default_fields_check = {}
|
14
|
+
@formatted_params_after_custom_fields_check = {}
|
15
|
+
@formatted_params_after_custom_overall_check = {}
|
16
|
+
@custom_check_errors = {}
|
12
17
|
end
|
13
18
|
|
14
|
-
def self.init
|
15
|
-
raise "This field's type must be boolean." if [required, many].any? { |value| !value.in? [true, false] }
|
19
|
+
def self.init(required: true, many: false, default: nil, allow_nil: false)
|
20
|
+
raise "This field's type must be boolean." if [required, many, allow_nil].any? { |value| !value.in? [true, false] }
|
16
21
|
|
17
22
|
type = many ? 'nested_hashs' : 'nested_hash'
|
23
|
+
|
18
24
|
{
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
25
|
+
type: type,
|
26
|
+
required: required,
|
27
|
+
default: default,
|
28
|
+
allow_nil: allow_nil,
|
29
|
+
many: many,
|
30
|
+
class: self
|
23
31
|
}
|
24
32
|
end
|
25
33
|
|
26
|
-
def raise_error
|
27
|
-
raise
|
34
|
+
def raise_error(message = DEFAULT_MESSAGE_ERROR)
|
35
|
+
raise GeneralError.new(message)
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_error(message, key = nil)
|
39
|
+
raise ParamsChecker::FieldError.new({
|
40
|
+
message: message,
|
41
|
+
key: key,
|
42
|
+
})
|
28
43
|
end
|
29
44
|
|
30
45
|
def call
|
31
|
-
|
32
|
-
error_exist? &&
|
46
|
+
default_fields_check && custom_check
|
47
|
+
error_exist? && add_errors
|
33
48
|
formatted_params
|
34
|
-
rescue => e
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
|
39
|
-
|
40
|
-
# "message": "Invalid data",
|
41
|
-
# "details": {
|
42
|
-
# "purchase_order_items": [
|
43
|
-
# {
|
44
|
-
# "errors": {
|
45
|
-
# "message": "Material not exists.",
|
46
|
-
# "details": {}
|
47
|
-
# }
|
48
|
-
# }
|
49
|
-
# ]
|
50
|
-
# }
|
51
|
-
# }
|
52
|
-
# }
|
53
|
-
# new:
|
54
|
-
# {
|
55
|
-
# "errors": {
|
56
|
-
# "message": "Material not exists.",
|
57
|
-
# "details": {}
|
58
|
-
# }
|
59
|
-
# }
|
60
|
-
if e.class.name == 'ParamsChecker::MyError' && is_outest_hash
|
61
|
-
errors.add(:errors, {
|
62
|
-
message: e,
|
63
|
-
details: {}
|
64
|
-
})
|
65
|
-
else
|
66
|
-
raise e
|
49
|
+
rescue ParamsChecker::GeneralError => e
|
50
|
+
# if is the outest hash, add error
|
51
|
+
# if is not, keep raising error, bubble up to the outest hash,
|
52
|
+
# then the outest hash will add error
|
53
|
+
unless is_outest_hash
|
54
|
+
raise e
|
67
55
|
end
|
56
|
+
|
57
|
+
errors.add(
|
58
|
+
:errors,
|
59
|
+
{
|
60
|
+
message: e.message,
|
61
|
+
error_type: 'general_error'
|
62
|
+
}
|
63
|
+
)
|
68
64
|
end
|
69
65
|
|
70
66
|
def error_exist?
|
71
|
-
|
67
|
+
errors.present? && errors.is_a?(Hash) || @custom_check_errors.present?
|
68
|
+
end
|
69
|
+
|
70
|
+
def default_fields_check
|
71
|
+
params_is_not_a_hash = !params.is_a?(ActionController::Parameters) && !params.is_a?(Hash)
|
72
|
+
|
73
|
+
if params_is_not_a_hash
|
74
|
+
errors.add(:error, 'ParamsChecker only receive object or ActionController::Parameters as input.')
|
75
|
+
end
|
76
|
+
|
77
|
+
all_fields_of_params_are_valid?
|
72
78
|
end
|
73
79
|
|
74
|
-
def
|
75
|
-
|
76
|
-
errors.add(:error, "ParamsChecker only receive object or ActionController::Parameters as input.") unless params_is_a_hash
|
77
|
-
params_is_a_hash && all_fields_are_valid
|
80
|
+
def custom_check
|
81
|
+
fields_check && overall_check
|
78
82
|
end
|
79
83
|
|
80
|
-
def
|
81
|
-
|
84
|
+
def all_fields_of_params_are_valid?
|
85
|
+
@all_fields_of_params_are_valid ||= field_valids.all?(true)
|
86
|
+
end
|
82
87
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
def data_valid? key
|
91
|
-
if value_need_to_be_present?(key)
|
92
|
-
if value_present?(key)
|
93
|
-
if value_valid?(key)
|
94
|
-
true
|
95
|
-
else
|
96
|
-
false
|
97
|
-
end
|
98
|
-
else
|
99
|
-
errors.add(key, 'This field is required.')
|
100
|
-
false
|
101
|
-
end
|
102
|
-
else
|
103
|
-
if value_present?(key)
|
104
|
-
if value_valid?(key)
|
105
|
-
true
|
106
|
-
else
|
107
|
-
false
|
108
|
-
end
|
109
|
-
else
|
110
|
-
true
|
88
|
+
def field_valids
|
89
|
+
@field_valids ||=
|
90
|
+
schema.map do |key, _|
|
91
|
+
set_default_value(key) if need_to_set_default_value?(key)
|
92
|
+
|
93
|
+
field_is_valid?(key)
|
111
94
|
end
|
112
|
-
end
|
113
95
|
end
|
114
96
|
|
115
|
-
def
|
116
|
-
|
117
|
-
@params[key].nil? && @params[key] = fields[key][:default]
|
97
|
+
def field_is_valid?(key)
|
98
|
+
return value_valid?(key) if value_present?(key)
|
118
99
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
100
|
+
return true unless value_need_to_be_present?(key)
|
101
|
+
|
102
|
+
errors.add(key, 'This field is required.')
|
103
|
+
false
|
123
104
|
end
|
124
105
|
|
125
|
-
def
|
106
|
+
def need_to_set_default_value?(key)
|
107
|
+
value_is_nil = @params[key].nil?
|
108
|
+
schema_field_has_default_value_key = schema[key].key?(:default)
|
109
|
+
default_value_is_set = !schema[key][:default].nil?
|
110
|
+
|
111
|
+
value_is_nil &&
|
112
|
+
schema_field_has_default_value_key &&
|
113
|
+
default_value_is_set
|
114
|
+
end
|
115
|
+
|
116
|
+
def set_default_value(key)
|
117
|
+
@params[key] = schema[key][:default]
|
118
|
+
end
|
119
|
+
|
120
|
+
def value_need_to_be_present?(key)
|
121
|
+
return true if schema[key].key?(:default) && !schema[key][:default].nil?
|
122
|
+
|
123
|
+
schema[key][:required]
|
124
|
+
end
|
125
|
+
|
126
|
+
def value_present?(key)
|
126
127
|
params.key?(key)
|
127
128
|
end
|
128
129
|
|
129
|
-
def value_valid?
|
130
|
-
cmd = check_base_on_field_type
|
130
|
+
def value_valid?(key)
|
131
|
+
cmd = check_base_on_field_type(key)
|
131
132
|
if cmd.success?
|
132
|
-
|
133
|
+
@formatted_params_after_default_fields_check[key] = cmd.result
|
133
134
|
else
|
134
|
-
|
135
|
+
errors.add(key, cmd.errors[key])
|
135
136
|
end
|
136
137
|
cmd.success?
|
137
138
|
end
|
138
139
|
|
139
|
-
def
|
140
|
-
|
141
|
-
|
142
|
-
|
140
|
+
def schema
|
141
|
+
@schema ||= init.each_with_object({}) do |error, hash|
|
142
|
+
key, value = error
|
143
|
+
hash[key] = value
|
143
144
|
end
|
144
|
-
@fields ||= field_params
|
145
145
|
end
|
146
146
|
|
147
|
-
def check_base_on_field_type
|
148
|
-
case
|
147
|
+
def check_base_on_field_type(key)
|
148
|
+
case schema[key][:type]
|
149
149
|
when 'num'
|
150
|
-
|
151
|
-
when 'int'
|
152
|
-
|
150
|
+
ParamChecker::NumParamChecker.call(key, schema, params)
|
151
|
+
when 'int'
|
152
|
+
ParamChecker::IntParamChecker.call(key, schema, params)
|
153
153
|
when 'char'
|
154
|
-
|
154
|
+
ParamChecker::CharParamChecker.call(key, schema, params)
|
155
155
|
when 'text'
|
156
|
-
|
156
|
+
ParamChecker::CharParamChecker.call(key, schema, params)
|
157
157
|
when 'arr'
|
158
|
-
|
158
|
+
ParamChecker::ArrParamChecker.call(key, schema, params)
|
159
|
+
when 'hash'
|
160
|
+
ParamChecker::HashParamChecker.call(key, schema, params)
|
159
161
|
when 'nested_hash'
|
160
|
-
|
162
|
+
ParamChecker::NestedHashChecker.call(key, schema, params, context)
|
161
163
|
when 'nested_hashs'
|
162
|
-
|
164
|
+
ParamChecker::NestedHashsChecker.call(key, schema, params, context)
|
163
165
|
when 'date'
|
164
|
-
|
166
|
+
ParamChecker::DateParamChecker.call(key, schema, params)
|
165
167
|
when 'time'
|
166
|
-
|
168
|
+
ParamChecker::TimeParamChecker.call(key, schema, params)
|
167
169
|
when 'datetime'
|
168
|
-
|
169
|
-
when 'email'
|
170
|
-
ParamChecker::EmailParamChecker.call key, fields, params
|
170
|
+
ParamChecker::DateTimeParamChecker.call(key, schema, params)
|
171
171
|
when 'boolean'
|
172
|
-
|
172
|
+
ParamChecker::BooleanChecker.call(key, schema, params)
|
173
173
|
when 'file'
|
174
|
-
|
174
|
+
ParamChecker::FileChecker.call(key, schema, params)
|
175
175
|
end
|
176
176
|
end
|
177
177
|
|
178
|
-
def
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
def specify_field_checks
|
183
|
-
@formatted_params_after_custom_specify_field_checks = formatted_params_after_default_check
|
184
|
-
fields.each do |key, value|
|
178
|
+
def fields_check
|
179
|
+
@formatted_params_after_custom_fields_check = formatted_params_after_default_fields_check
|
180
|
+
schema.each do |key, _|
|
185
181
|
# next unless self.methods.grep(/check_#{key}/).length > 0
|
186
|
-
|
187
|
-
|
188
|
-
|
182
|
+
need_to_check = "check_#{key}".to_sym.in?(methods)
|
183
|
+
passed_default_check = errors[key].nil?
|
184
|
+
|
185
|
+
next unless need_to_check && passed_default_check
|
186
|
+
|
187
|
+
field_check(key)
|
189
188
|
end
|
190
189
|
end
|
191
190
|
|
192
|
-
def
|
191
|
+
def field_check(key)
|
193
192
|
check_method = "check_#{key}"
|
194
193
|
total_parameters = method(check_method).arity
|
195
|
-
#
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
194
|
+
# pp "========>total_parameters : ", total_parameters
|
195
|
+
|
196
|
+
value = if total_parameters == 1
|
197
|
+
# like check_name(name)
|
198
|
+
send(check_method, @formatted_params_after_default_fields_check[key])
|
199
|
+
elsif total_parameters == 2
|
200
|
+
# like check_name(name, opts)
|
201
|
+
send(check_method, @formatted_params_after_default_fields_check[key], @formatted_params_after_default_fields_check)
|
202
|
+
end
|
203
|
+
|
204
|
+
@formatted_params_after_custom_fields_check[key] = value
|
205
|
+
rescue ParamsChecker::FieldError => e
|
206
|
+
# binding.pry
|
207
|
+
key = e.data[:key].presence || key
|
208
|
+
@custom_check_errors[key] = e.data[:message]
|
200
209
|
end
|
201
210
|
|
202
|
-
def
|
203
|
-
@
|
211
|
+
def overall_check
|
212
|
+
@formatted_params_after_custom_overall_check = check(formatted_params_after_custom_fields_check)
|
213
|
+
rescue ParamsChecker::FieldError => e
|
214
|
+
key = e.data[:key]
|
215
|
+
@custom_check_errors[key] = e.data[:message]
|
204
216
|
end
|
205
217
|
|
206
218
|
def init
|
207
219
|
{}
|
208
220
|
end
|
209
221
|
|
210
|
-
def check
|
222
|
+
def check(params)
|
211
223
|
params
|
212
224
|
end
|
213
225
|
|
214
226
|
def formatted_params
|
215
|
-
|
227
|
+
formatted_params_after_custom_overall_check
|
216
228
|
end
|
217
229
|
|
218
|
-
def
|
219
|
-
# only add errors
|
220
|
-
return unless is_outest_hash
|
230
|
+
def add_errors
|
231
|
+
# only add errors at the outest hash
|
232
|
+
# return unless is_outest_hash
|
233
|
+
|
234
|
+
field_errors = errors.each_with_object({}) do |error, hash|
|
235
|
+
key, value = error
|
236
|
+
value = value.is_a?(Array) ? value[0] : value
|
237
|
+
hash[key] = value
|
221
238
|
|
222
|
-
|
223
|
-
errors.each do |key, value|
|
224
|
-
details[key] = value
|
225
|
-
errors.delete(key)
|
239
|
+
errors.delete(key)
|
226
240
|
end
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
241
|
+
|
242
|
+
@custom_check_errors.each do |key, value|
|
243
|
+
field_errors[key] = value
|
244
|
+
end
|
245
|
+
|
246
|
+
errors.add(
|
247
|
+
:errors,
|
248
|
+
{
|
249
|
+
message: DEFAULT_MESSAGE_ERROR,
|
250
|
+
error_type: 'fields_errors',
|
251
|
+
field_errors: field_errors
|
252
|
+
}
|
253
|
+
)
|
231
254
|
end
|
232
255
|
|
233
|
-
attr_accessor :params,
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
256
|
+
attr_accessor :params,
|
257
|
+
:context,
|
258
|
+
:formatted_params_after_default_fields_check,
|
259
|
+
:formatted_params_after_custom_fields_check,
|
260
|
+
:formatted_params_after_custom_overall_check,
|
261
|
+
:is_outest_hash,
|
262
|
+
# :message,
|
263
|
+
:custom_check_errors
|
238
264
|
end
|
239
265
|
end
|
240
266
|
|
241
|
-
|
242
|
-
# return
|
243
|
-
# return false if value_need_to_be_present?(key) && value_present?(key) &&
|
244
|
-
# return false if value_need_to_be_present?(key) && !value_present?(key) && value_valid?(key)
|
245
|
-
# return
|
246
|
-
# return
|
247
|
-
# return
|
248
|
-
# return true if !value_need_to_be_present?(key) && !value_present?(key) && value_valid?(key)
|
249
|
-
# return true if !value_need_to_be_present?(key) && !value_present?(key) && !value_valid?(key)
|
267
|
+
# return true if value_need_to_be_present?(key) && value_present?(key) && value_valid?(key)
|
268
|
+
# return false if value_need_to_be_present?(key) && value_present?(key) && !value_valid?(key)
|
269
|
+
# return false if value_need_to_be_present?(key) && !value_present?(key) && value_valid?(key)
|
270
|
+
# return false if value_need_to_be_present?(key) && !value_present?(key) && !value_valid?(key)
|
271
|
+
# return true if !value_need_to_be_present?(key) && value_present?(key) && value_valid?(key)
|
272
|
+
# return false if !value_need_to_be_present?(key) && value_present?(key) && !value_valid?(key)
|
273
|
+
# return true if !value_need_to_be_present?(key) && !value_present?(key) && value_valid?(key)
|
274
|
+
# return true if !value_need_to_be_present?(key) && !value_present?(key) && !value_valid?(key)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Constants
|
4
|
+
ERROR_MESSAGES = {
|
5
|
+
required: 'This field is required.',
|
6
|
+
blank: 'This field cannot be blank.',
|
7
|
+
empty: 'This field cannot be empty.',
|
8
|
+
|
9
|
+
type: {
|
10
|
+
string: "This field's type must be string.",
|
11
|
+
file: "This field's type must be file.",
|
12
|
+
hash: "This field's type must be hash.",
|
13
|
+
nested_hash: "This field's type must be object or ActionController::Parameters.",
|
14
|
+
array: "This field's type must be array.",
|
15
|
+
integer: "This field's type must be integer.",
|
16
|
+
numeric: "This field's type must be numeric.",
|
17
|
+
boolean: "This field's type must be boolean.",
|
18
|
+
date: 'Invalid date.',
|
19
|
+
time: 'Invalid time.',
|
20
|
+
datetime: 'Invalid datetime.'
|
21
|
+
},
|
22
|
+
|
23
|
+
length: {
|
24
|
+
text: 'Invalid text length.',
|
25
|
+
char: 'Invalid char length.'
|
26
|
+
},
|
27
|
+
|
28
|
+
value: {
|
29
|
+
numeric: 'Invalid numeric value.',
|
30
|
+
integer: 'Invalid integer value.'
|
31
|
+
}
|
32
|
+
}.freeze
|
33
|
+
|
34
|
+
def get_integer_value_error_message(min: -2_000_000_000_000, max: 2_000_000_000_000)
|
35
|
+
"This integer field's value must be in range from #{min} to #{max}."
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_numeric_value_error_message(min: -2_000_000_000_000, max: 2_000_000_000_000)
|
39
|
+
"This numeric field's value must be in range from #{min} to #{max}."
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_string_length_error_message(min_length: 0, max_length: 30_000)
|
43
|
+
"This string field's length must be in range from #{min_length} to #{max_length}."
|
44
|
+
end
|
45
|
+
end
|