request_params_validation 0.1.1 → 0.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 532c37904a1c0cbab6d818039ebeabe0886eae35f2f8b7f911931ca41b323712
4
- data.tar.gz: ea982841155186b8a46de89b449c30031aa1fdb0017f7f748becdd1225235427
3
+ metadata.gz: 2d0b040bc6ef9353a9c6d8e4f48c195cebb4e2547bd66c6c709e57605cf6c18d
4
+ data.tar.gz: e226a8483f9655aacb337de251363e23c24ef517d4005f577ca470a5e7bd8fd5
5
5
  SHA512:
6
- metadata.gz: 6187c851e82740b4e00f47c0b9f40b2930312eb349467b6e6e2197d50134c27e3cd4bdc77a53778881c68b08caafcd897257e4d25412f86213cbaa8d519f687d
7
- data.tar.gz: 91bb251b9af8c43b901c1709abb4ff0590dade190ffe2be320db5f86691e648f42c93610b469e948ec17b5defaca078865b93c5c755f880982a62469bee64d86
6
+ metadata.gz: d9e496129c0335c2ef2bb2ba9ee5c0715f4d49ca3890d428d8200e329d7e5dcbaf8fd45625fa3325132e95967c7e496eaff6f5234f7b5a867f8972f31083e520
7
+ data.tar.gz: ba5c464e0fe423f287a7c5808b401f884a7288520b328f8bfac2f54cd9b5d835f3f255ab6974252fb8d7136ccf5b267959f8f46d163aa69bc8697b0eae772d1f
data/README.md CHANGED
@@ -1,7 +1,9 @@
1
1
  # RequestParamsValidation
2
2
  _Request parameters validations, type coercion and filtering for Rails params_
3
3
 
4
+ [![Gem Version](https://badge.fury.io/rb/request_params_validation.svg)](https://badge.fury.io/rb/request_params_validation)
4
5
  [![CircleCI](https://circleci.com/gh/felipefava/request_params_validation.svg?style=shield&circle-token=a404cb4fd87e219299caeb36e1685ab75d335b84)](https://circleci.com/gh/felipefava/request_params_validation)
6
+ [![Codacy Quality Badge](https://api.codacy.com/project/badge/Grade/6ed6582228bd429a94dfabaa82071455)](https://www.codacy.com/manual/felipefava/request_params_validation?utm_source=github.com&utm_medium=referral&utm_content=felipefava/request_params_validation&utm_campaign=Badge_Grade)
5
7
 
6
8
  ## Introduction
7
9
  Validates the request params outside your controller logic in order to get a clean nice code, and
@@ -43,7 +45,7 @@ documentation and allows to keep controllers code clean, ensuring that `params`
43
45
  always have the parameters you suppose to receive.
44
46
 
45
47
  The default path for the definitions files is `app/definitions`, and their names should be the same
46
- as their respective controller's name, but ending with the suffix `_definition`. They also should
48
+ as their respective controller's name, but ending with the suffix `_definition`. They should also
47
49
  respect the folder structure of the controllers folder. Please see the following project structure
48
50
  to clarify the idea:
49
51
 
@@ -93,15 +95,15 @@ and `notify`:
93
95
 
94
96
  class UsersController < ApplicationController
95
97
  def create
96
- ...
98
+ params # will have only the defined parameters
97
99
  end
98
100
 
99
101
  def notify
100
- ...
102
+ params # will have only the defined parameters
101
103
  end
102
104
 
103
105
  def another_action
104
- ...
106
+ params # will have whatever the user sends
105
107
  end
106
108
  end
107
109
  ```
@@ -111,25 +113,25 @@ Then, we will need to create the definition for the `users` resource:
111
113
  ```ruby
112
114
  # app/definitions/users_definition.rb
113
115
 
114
- RequestParamsValidation.define do |users|
115
- users.action :create do |create|
116
- users.request do |params|
117
- params.required :user, type: :hash do |user|
118
- user.required :first_name, type: :string
119
- user.required :last_name, type: :string
120
- user.required :emails, type: :array, elements: :email
121
- user.required :birth_date,
122
- type: :datetime,
123
- validate: lambda { |value| value <= 18.years.ago.to_date }
116
+ RequestParamsValidation.define do
117
+ action :create do
118
+ request do
119
+ required :user, type: :hash do
120
+ required :first_name, type: :string
121
+ required :last_name, type: :string
122
+ required :emails, type: :array, elements: :email
123
+ required :birth_date,
124
+ type: :datetime,
125
+ validate: lambda { |value| value <= 18.years.ago.to_date }
124
126
  end
125
127
  end
126
128
  end
127
129
 
128
- users.action :notify do |notify|
129
- notify.request do |params|
130
- params.required :user_id, type: :integer
131
- params.required :message, type: :string, length: { min: 10, max: 250 }
132
- params.optional :by, inclusion: %w(email text_msg push), default: :email
130
+ action :notify do
131
+ request do
132
+ required :user_id, type: :integer
133
+ required :message, type: :string, length: { min: 10, max: 250 }
134
+ optional :by, inclusion: %w(email text_msg push), default: :email
133
135
  end
134
136
  end
135
137
  end
@@ -169,25 +171,25 @@ param. Otherwise use the `optional` method. For default, required parameters don
169
171
  values, if you would like to allow them for that parameter, you can use the option `allow_blank`
170
172
 
171
173
  ```ruby
172
- some_action.request do |params|
173
- params.required :key_1
174
- params.required :key_2, allow_blank: true
175
- params.optional :key_3
174
+ request do
175
+ required :key_1
176
+ required :key_2, allow_blank: true
177
+ optional :key_3
176
178
  end
177
179
  ```
178
180
 
179
181
  ### Types
180
182
  The `type` option specified the type of the parameter. The supported types are:
181
183
 
182
- 1. hash
183
- 2. array
184
- 3. string
185
- 4. integer
186
- 5. decimal
187
- 6. boolean
188
- 7. date
189
- 9. datetime
190
- 9. email
184
+ 1. hash
185
+ 2. array
186
+ 3. string
187
+ 4. integer
188
+ 5. decimal
189
+ 6. boolean
190
+ 7. date
191
+ 8. datetime
192
+ 9. email
191
193
 
192
194
  So if this option is present, the gem will validate that the value of the parameter matches with
193
195
  the specified type. And if it does, it will convert the value to the right type. This means that
@@ -199,9 +201,9 @@ configuration option `extend.types`. See [here](#configuration) all globals
199
201
  configuration options.
200
202
 
201
203
  ```ruby
202
- some_action.request do |params|
203
- params.required :key_1, type: :boolean
204
- params.required :key_2, type: :decimal
204
+ request do
205
+ required :key_1, type: :boolean
206
+ required :key_2, type: :decimal
205
207
  # ...
206
208
  end
207
209
  ```
@@ -214,14 +216,14 @@ If no block is passed, the gem will only check that the value of the parameter b
214
216
  object, without validating the content of it.
215
217
 
216
218
  ```ruby
217
- some_action.request do |params|
219
+ request do
218
220
  # Allows any keys and values for the hash
219
- params.required :key_1, type: :hash
221
+ required :key_1, type: :hash
220
222
 
221
223
  # Only allows the keys nested_key_1 and nested_key_2
222
- params.required :key_2, type: :hash do |key_name|
223
- key_name.required :nested_key_1, type: :string
224
- key_name.required :nested_key_2, type: :integer
224
+ required :key_2, type: :hash do
225
+ required :nested_key_1, type: :string
226
+ required :nested_key_2, type: :integer
225
227
  end
226
228
  end
227
229
  ```
@@ -235,20 +237,20 @@ The value for this option can be a type or a hash. `elements: :integer` is equiv
235
237
  `elements: { type: :integer }`.
236
238
 
237
239
  The second way is useful when you want to validate other things of the elements than just the
238
- type. The option elements accepts all validations options.
240
+ type. The option `elements` accepts all validations options.
239
241
 
240
242
  ```ruby
241
- some_action.request do |params|
243
+ request do
242
244
  # Allows any value for the elements of the array
243
- params.required :key_1, type: :array
245
+ required :key_1, type: :array
244
246
 
245
247
  # Only allows decimals with a value less than 1_000 for the elements of the array
246
- params.required :key_2, type: :array, elements: { type: :decimal, value: { max: 1_000 }
248
+ required :key_2, type: :array, elements: { type: :decimal, value: { max: 1_000 } }
247
249
 
248
250
  # Only allows objects with a required key 'nested_key' of type 'email' for the
249
251
  # elements of the array
250
- params.required :key_3, type: :array, elements: :hash do |key_3|
251
- key_3.required :nested_key, type: :email
252
+ required :key_3, type: :array, elements: :hash do
253
+ required :nested_key, type: :email
252
254
  end
253
255
  end
254
256
  ```
@@ -260,7 +262,7 @@ Any value is a valid string.
260
262
  Accepts only valid integers like `5` or `"5"`.
261
263
 
262
264
  #### Decimal type
263
- Accepts only valid decimals like `5` or `1.5` or `10.45`. With decimals parameters you can use
265
+ Accepts only valid decimals like `5` or `"1.5"` or `10.45`. With decimals parameters you can use
264
266
  the option `precision`. Go [here](#precision) for more details about this option.
265
267
 
266
268
  #### Boolean type
@@ -282,10 +284,11 @@ will be converter to a Date object like `Wed, 04 Oct 1995`.
282
284
  However, they are cases when you only want to accept a specific format for a date, like
283
285
  `"%Y-%m-%e"`. In this cases you have two options.
284
286
 
285
- 1. Use the global configuration option `format.date`, so all date types must have the specified
286
- format through all the requests. See [here](#configuration) all globals configuration
287
- options.
288
- 2. Specify the option `format: "%Y-%m-%e"` locally.
287
+ 1. Use the global configuration option `format.date`, so all date types must have the specified
288
+ format through all the requests. See [here](#configuration) all globals configuration
289
+ options.
290
+
291
+ 2. Specify the option `format: "%Y-%m-%e"` locally.
289
292
 
290
293
  You can perfectly use both approaches, but the second one will locally override the first one on
291
294
  that parameter validation.
@@ -294,9 +297,9 @@ Notice that if no format is specified, the date will be validated using the ruby
294
297
  method.
295
298
 
296
299
  ```ruby
297
- some_action.request do |params|
298
- params.required :key_1, type: :date
299
- params.required :key_2, type: :date, format: '%Y-%m-%e'
300
+ request do
301
+ required :key_1, type: :date
302
+ required :key_2, type: :date, format: '%Y-%m-%e'
300
303
  end
301
304
  ```
302
305
 
@@ -317,9 +320,9 @@ Besides from the `in` option, you can also use the `message` option for passing
317
320
  detail when the parameter is not valid.
318
321
 
319
322
  ```ruby
320
- some_action.request do |params|
321
- params.required :key_1, type: :string, inclusion: %w(asc desc)
322
- params.required :key_2,
323
+ request do
324
+ required :key_1, type: :string, inclusion: %w(asc desc)
325
+ required :key_2,
323
326
  type: :string,
324
327
  inclusion: { in: %w(s m l), message: 'Value is not a valid size' }
325
328
  end
@@ -335,12 +338,11 @@ Besides from the `min` and `max` options, you can also use the `message` option
335
338
  custom error detail when the parameter is not valid.
336
339
 
337
340
  ```ruby
338
- some_action.request do |params|
339
- params.required :key_1, type: :string, length: 10
340
- params.required :key_2, type: :string, length: { min: 5, max: 12 }
341
- params.required :key_3, type: :array, elements: :email, length: { max: 3 }
342
- params.required :key_4, type: :string, length: { max: 25,
343
- message: '25 characters is the maximum allowed' }
341
+ request do
342
+ required :key_1, type: :string, length: 10
343
+ required :key_2, type: :string, length: { min: 5, max: 12 }
344
+ required :key_3, type: :array, elements: :email, length: { max: 3 }
345
+ required :key_4, type: :string, length: { max: 25, message: '25 characters is the maximum allowed' }
344
346
  end
345
347
  ```
346
348
 
@@ -350,15 +352,15 @@ The `value` option is for validating the value size of numerics parameters.
350
352
  The value for this option is a hash with the following options: `min`, `max` and `message`.
351
353
 
352
354
  ```ruby
353
- some_action.request do |params|
354
- params.required :key_1, type: :integer, value: { min: 0 }
355
- params.required :key_2, type: :integer, value: { max: 1_000_000, message: 'Value too big!' }
356
- params.required :key_3, type: :decimal, value: { min: 0, max: 1 }
355
+ request do
356
+ required :key_1, type: :integer, value: { min: 0 }
357
+ required :key_2, type: :integer, value: { max: 1_000_000, message: 'Value too big!' }
358
+ required :key_3, type: :decimal, value: { min: 0, max: 1 }
357
359
  end
358
360
  ```
359
361
 
360
362
  ### Format
361
- The `format` option allows to validate de format of the value with a regular expression.
363
+ The `format` option allows to validate the format of the value with a regular expression.
362
364
 
363
365
  The value for this option is a `regexp`, `string` or a `hash`. The string value is only valid
364
366
  when the type is a `date` or a `datetime`. Otherwise, you should use a regexp. The options for
@@ -369,10 +371,10 @@ So, for `date` and `datetime` types, `format: '%u%F'` is equivalent to
369
371
  equivalent to `format: { regexp: /^5[1-5]\d{14}$/ }`.
370
372
 
371
373
  ```ruby
372
- some_action.request do |params|
373
- params.required :key_1, type: :string, format: /^5[1-5]\d{14}$/
374
- params.required :key_2, type: :string, format: { regexp: /^1.*/,
375
- message: 'Value should start with a 1' }
374
+ request do
375
+ required :key_1, type: :string, format: /^5[1-5]\d{14}$/
376
+ required :key_2, type: :string, format: { regexp: /^1.*/,
377
+ message: 'Value should start with a 1' }
376
378
  end
377
379
  ```
378
380
 
@@ -385,9 +387,9 @@ This option accepts a Proc as value or a hash. For example,
385
387
  also accepts the `message` option.
386
388
 
387
389
  ```ruby
388
- some_action.request do |params|
389
- params.required :key_1, type: :date, validate: { function: lambda { |value| value >= Date.today },
390
- message: 'The date can not be in the past' }
390
+ request do
391
+ required :key_1, type: :date, validate: { function: lambda { |value| value >= Date.today },
392
+ message: 'The date can not be in the past' }
391
393
  end
392
394
  ```
393
395
 
@@ -398,14 +400,14 @@ the specified type.
398
400
 
399
401
  If you want to set a precision value to all `decimal` parameters, you can use the global
400
402
  configuration option `format.decimal_precision`. Keep in mind that if you set the `precision`
401
- option on a parameter, it will locally override the global configuration. See here for all
402
- globals configuration options.
403
+ option on a parameter, it will locally override the global configuration. See [here](#configuration)
404
+ for all globals configuration options.
403
405
 
404
406
  This option accepts an integer as value.
405
407
 
406
408
  ```ruby
407
- some_action.request do |params|
408
- params.required :key_1, type: :decimal, precision: 2
409
+ request do
410
+ required :key_1, type: :decimal, precision: 2
409
411
  end
410
412
  ```
411
413
 
@@ -416,9 +418,9 @@ present.
416
418
  The value for the option `default` could be anything, including a proc.
417
419
 
418
420
  ```ruby
419
- some_action.request do |params|
420
- params.optional :key_1, type: :string, default: 'Jane'
421
- params.optional :key_2, type: :string, default: lambda { Date.today.strftime('%A') }
421
+ request do
422
+ optional :key_1, type: :string, default: 'Jane'
423
+ optional :key_2, type: :string, default: lambda { Date.today.strftime('%A') }
422
424
  end
423
425
  ```
424
426
 
@@ -432,17 +434,54 @@ specified in the definition. So, `transform: :strip` is equivalent to
432
434
  `transform: lambda { |value| value.strip }`.
433
435
 
434
436
  ```ruby
435
- some_action.request do |params|
436
- params.optional :key_1, type: :string, transform: :strip
437
- params.optional :key_2,
438
- type: :string,
439
- format: /^\d{3}-\d{3}-\d{3}$/,
440
- transform: lambda { |value| value.gsub(/-/, '') }
437
+ request do
438
+ optional :key_1, type: :string, transform: :strip
439
+ optional :key_2,
440
+ type: :string,
441
+ format: /^\d{3}-\d{3}-\d{3}$/,
442
+ transform: lambda { |value| value.gsub(/-/, '') }
441
443
  end
442
444
  ```
443
445
 
446
+ ### Rename Parameters
447
+ You can rename parameters using the `as` option.
448
+
449
+ ```ruby
450
+ request do
451
+ required :email_address, type: :email, as: :email
452
+ end
453
+ ```
454
+
455
+ This means that in the request params you expect a valid email value in the key `email_address`,
456
+ but in your controller you will access with the key `email`.
457
+
458
+ ### Dependent Parameters
459
+ If you want to receive and validate a parameter only if another one is given, you can use
460
+ the `is_given` option.
461
+
462
+ ```ruby
463
+ request do
464
+ optional :label, type: :string
465
+ required :description, type: :string, if_given: :label
466
+ #...
467
+ required :card_type, inclusion: %w(credit_card debit_card)
468
+ required :ccv, if_given: { card_type: lambda { |value| value == 'credit_card' } }
469
+ end
470
+ ```
471
+
472
+ On the example above, the param `description` will be only validated if the param `label` is present.
473
+ RequestParamsValidation will use the method `blank?` to check that. On the other hand, the param
474
+ `ccv` will only be validated if the param `type_card` is equal to the string `credit_card`.
475
+
476
+ Notice that if the global option `filter_params` is set to `true` (default behaviour), then the
477
+ dependent parameters will be filtered from the `params object` if they haven't beeen validated.
478
+ This way we make sure to only receive those parameters that have been validated against our request
479
+ definitions.
480
+
481
+ Be aware that if you rename a param, then you should use the new name in the `if_given` option.
482
+
444
483
  ---
445
- **NOTE**
484
+ ### NOTE
446
485
 
447
486
  RequestParamsValidation will start validating the presence of the parameters. Then, if the value is
448
487
  not present and the parameter has a default value, it will assign that value and not execute any
@@ -450,8 +489,8 @@ further validation. Otherwise, it will validate the type, convert it to the righ
450
489
  continue with the others validations. So, all others validations will be executed with the parameter
451
490
  value already converter to the specified type, so keep in mind that at defining the validations.
452
491
 
453
-
454
492
  ## Errors & Messages
493
+
455
494
  For default, when a required parameter failed the presence validation, the exception
456
495
  `RequestParamsValidation::MissingParameterError` will be raised. If it failed for any of the others
457
496
  validations, the raised exception will be `RequestParamsValidation::InvalidParameterValueError`
@@ -502,17 +541,15 @@ an element of an array or not. If you **have specified the `message` option in t
502
541
  definition**, then the details will be that value, otherwise it will took a default value from
503
542
  the table below:
504
543
 
505
-
506
- | Failure | Default Message |
507
- | ------------------------- | ---------------------------------------------------- |
508
- | Missing parameter | N/A |
509
- | Invalid type | - `Value should be a valid %{param_type}` <br> - `All elements of the array should be a valid %{type}` <br> If has `date` or `datetime` type with specified `format`: <br> &nbsp;&nbsp;&nbsp; - ` with the format %{format}` is added to the message |
510
- | Invalid inclusion | - `Value should be in %{include_in}` <br> - `All elements values of the array should have be in %{include_in}` |
511
- | Invalid length | - `Length should be greater or equal than %{min}` <br> - `Length should be less or equal than %{max}` <br> - `Length should be equal to %{min/max}` </br> - `Length should be between %{min} and %{max}` <br> - `All elements of the array should have a length ...` |
512
- | Invalid value size | - `Value should be greater or equal than %{min}` <br> - `Value should be less or equal than %{max}` <br> - `Value should be between %{min} and %{max}` <br> - `All elements of the array should have a value ...` |
513
- | Invalid format | - `Value format is invalid` <br> - `An element of the array has an invalid format` |
514
- | Invalid custom validation | N/A |
515
-
544
+ | Failure | Default Message |
545
+ | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
546
+ | Missing parameter | N/A |
547
+ | Invalid type | - `Value should be a valid %{param_type}` <br> - `All elements of the array should be a valid %{type}` <br> If has `date` or `datetime` type with specified `format`: <br> &nbsp;&nbsp;&nbsp; - ` with the format %{format}` is added to the message |
548
+ | Invalid inclusion | - `Value should be in %{include_in}` <br> - `All elements values of the array should be in %{include_in}` |
549
+ | Invalid length | - `Length should be greater or equal than %{min}` <br> - `Length should be less or equal than %{max}` <br> - `Length should be equal to %{min/max}` </br> - `Length should be between %{min} and %{max}` <br> - `All elements of the array should have a length ...` |
550
+ | Invalid value size | - `Value should be greater or equal than %{min}` <br> - `Value should be less or equal than %{max}` <br> - `Value should be between %{min} and %{max}` <br> - `All elements of the array should have a value ...` |
551
+ | Invalid format | - `Value format is invalid` <br> - `An element of the array has an invalid format` |
552
+ | Invalid custom validation | N/A | |
516
553
 
517
554
  ### Custom Exceptions
518
555
  However, if the above is not enough for your app, and you need to fully customize the exceptions
@@ -534,24 +571,16 @@ end
534
571
  To see a complete initializer file of the configuration with all the options and their description,
535
572
  please see [here](./examples/initializer.rb).
536
573
 
537
- ## Future Work
538
- In the near future the plan is to continue adding features to the gem. Next incoming changes
539
- could be:
540
- - Add doc generation from the definitions
541
- - Add representations for DRY definitions
542
- - Add more options to the actions definitions
543
- - Add handler for responses
544
-
545
574
  ## Acknowledgments
546
575
  This gem is strongly inspired in a Ruby framework named [Angus](https://github.com/moove-it/angus)
547
576
  developed by [Moove It](https://moove-it.com/)
548
577
 
549
578
  ## Contributing
550
- 1. Fork it
551
- 2. Create your feature branch (git checkout -b my-new-feature)
552
- 3. Commit your changes (git commit -am 'Add some feature')
553
- 4. Push to the branch (git push origin my-new-feature)
554
- 5. Create a Pull Request
579
+ 1. Fork it
580
+ 2. Create your feature branch (git checkout -b my-new-feature)
581
+ 3. Commit your changes (git commit -am 'Add some feature')
582
+ 4. Push to the branch (git push origin my-new-feature)
583
+ 5. Create a Pull Request
555
584
 
556
585
  ## License
557
586
  This software is released under the MIT license. See the MIT-LICENSE file for more info.
@@ -5,9 +5,9 @@ module RequestParamsValidation
5
5
  module Definitions
6
6
  @@definitions = {}
7
7
 
8
- def self.load_all
8
+ def self.load_all(use_load = false)
9
9
  definitions_suffix = RequestParamsValidation.definitions_suffix
10
- Dir["#{definitions_path}/**/*#{definitions_suffix}.rb"].each { |file| load file }
10
+ Dir["#{definitions_path}/**/*#{definitions_suffix}.rb"].each { |f| use_load ? load(f) : require(f) }
11
11
  end
12
12
 
13
13
  def self.register_resource(&block)
@@ -16,7 +16,7 @@ module RequestParamsValidation
16
16
  resource_name = resource_name_from_block(&block)
17
17
  resource = Resource.new(resource_name)
18
18
 
19
- block.call(resource)
19
+ resource.instance_eval(&block)
20
20
 
21
21
  @@definitions[resource_name] = resource
22
22
  end
@@ -9,11 +9,11 @@ module RequestParamsValidation
9
9
  @name = name
10
10
  end
11
11
 
12
- def request
12
+ def request(&block)
13
13
  if block_given?
14
14
  @request = Request.new
15
15
 
16
- yield @request
16
+ @request.instance_eval(&block)
17
17
  else
18
18
  @request
19
19
  end
@@ -1,17 +1,17 @@
1
1
  require 'request_params_validation/params'
2
- require 'request_params_validation/exceptions/definitions_errors'
3
2
 
4
3
  module RequestParamsValidation
5
4
  module Definitions
6
5
  class Param
7
- attr_reader :key, :required, :allow_blank, :type, :transform, :decimal_precision,
8
- :inclusion, :length, :value, :format, :custom_validation, :elements
6
+ attr_reader :key, :required, :allow_blank, :type, :rename_as, :transform, :decimal_precision,
7
+ :inclusion, :length, :value, :format, :custom_validation, :if_given, :elements
9
8
 
10
9
  def initialize(options, &block)
11
10
  @key = options[:key]
12
11
  @required = options[:required]
13
12
  @allow_blank = options[:allow_blank]
14
13
  @type = options[:type].try(:to_sym)
14
+ @rename_as = options[:as].try(:to_sym)
15
15
  @default = options[:default]
16
16
 
17
17
  @transform = options[:transform]
@@ -23,6 +23,7 @@ module RequestParamsValidation
23
23
  @value = build_value_option(options[:value])
24
24
  @format = build_format_option(options[:format])
25
25
  @custom_validation = build_custom_validation_option(options[:validate])
26
+ @if_given = build_if_given_option(options[:if_given])
26
27
 
27
28
  @elements = build_elements_option(options[:elements], &block)
28
29
  @sub_definition = build_sub_definition(&block)
@@ -74,6 +75,26 @@ module RequestParamsValidation
74
75
  !!@custom_validation
75
76
  end
76
77
 
78
+ def rename?
79
+ !!@rename_as
80
+ end
81
+
82
+ def transform?
83
+ !!@transform
84
+ end
85
+
86
+ def skip?(request_params)
87
+ return false unless @if_given
88
+
89
+ if_given_param_value = request_params[@if_given.param]
90
+
91
+ if @if_given.function
92
+ !@if_given.function.call(if_given_param_value)
93
+ else
94
+ if_given_param_value.blank?
95
+ end
96
+ end
97
+
77
98
  private
78
99
 
79
100
  def build_inclusion_option(inclusion)
@@ -150,6 +171,20 @@ module RequestParamsValidation
150
171
  Struct.new(:function, :message).new(function, message)
151
172
  end
152
173
 
174
+ def build_if_given_option(if_given)
175
+ case if_given
176
+ when String, Symbol
177
+ param = if_given.to_sym
178
+ when Hash
179
+ param = if_given.first.try(:first)
180
+ function = if_given.first.try(:last)
181
+ end
182
+
183
+ return unless param
184
+
185
+ Struct.new(:param, :function).new(param, function)
186
+ end
187
+
153
188
  def build_elements_option(elements, &block)
154
189
  return unless @type == Params::ARRAY_TYPE
155
190
 
@@ -173,7 +208,7 @@ module RequestParamsValidation
173
208
 
174
209
  request = Request.new
175
210
 
176
- block.call(request) if block_given?
211
+ request.instance_eval(&block) if block_given?
177
212
 
178
213
  request.params
179
214
  end
@@ -11,16 +11,16 @@ module RequestParamsValidation
11
11
  @actions = {}
12
12
  end
13
13
 
14
- def action(action_name)
14
+ def action(action_name, &block)
15
15
  unless block_given?
16
16
  raise DefinitionArgumentError.new("Expecting block for action '#{action_name}'")
17
17
  end
18
18
 
19
- action_definition = Action.new(action_name.to_s)
19
+ action = Action.new(action_name.to_s)
20
20
 
21
- yield action_definition
21
+ action.instance_eval(&block)
22
22
 
23
- @actions[action_name.to_s] = action_definition
23
+ @actions[action_name.to_s] = action
24
24
  rescue DefinitionArgumentError => e
25
25
  e.resource = name
26
26
  raise
@@ -6,12 +6,12 @@ module RequestParamsValidation
6
6
  isolate_namespace RequestParamsValidation
7
7
 
8
8
  initializer 'request_params_validation.load_definitions' do
9
- RequestParamsValidation::Definitions.load_all
9
+ Definitions.load_all
10
10
  end
11
11
 
12
12
  initializer 'request_params_validation.add_helpers' do
13
13
  ActiveSupport.on_load :action_controller do
14
- include RequestParamsValidation::Helpers
14
+ include Helpers
15
15
  end
16
16
  end
17
17
  end
@@ -7,6 +7,8 @@ module RequestParamsValidation
7
7
 
8
8
  def self.validate!(definition, params)
9
9
  definition.each do |param_definition|
10
+ next if param_definition.skip?(params)
11
+
10
12
  validate_and_coerce_param(param_definition, params)
11
13
  end
12
14
 
@@ -16,8 +18,8 @@ module RequestParamsValidation
16
18
  def self.filter!(definition, params)
17
19
  extra_keys = [:controller, :action] # Keys added by Rails
18
20
 
19
- filter_params(definition, params, extra_keys).tap do |params|
20
- params.permit! if params.respond_to?(:permit!)
21
+ filter_params(definition, params, extra_keys).tap do |filtered_params|
22
+ filtered_params.permit! if filtered_params.respond_to?(:permit!)
21
23
  end
22
24
  end
23
25
 
@@ -26,8 +28,14 @@ module RequestParamsValidation
26
28
  value = params[key]
27
29
 
28
30
  value = Validator.new(param_definition, value).validate_and_coerce
31
+ value = Converter.apply_transformation(param_definition, value) if param_definition.transform?
29
32
 
30
- params[key] = value
33
+ if param_definition.rename?
34
+ params.delete(key)
35
+ params[param_definition.rename_as] = value
36
+ else
37
+ params[key] = value
38
+ end
31
39
  end
32
40
  private_class_method :validate_and_coerce_param
33
41
 
@@ -36,7 +44,9 @@ module RequestParamsValidation
36
44
  return params if definition.empty?
37
45
 
38
46
  params_keys = definition.map do |param_definition|
39
- key = param_definition.key
47
+ next if param_definition.skip?(params)
48
+
49
+ key = param_definition.rename? ? param_definition.rename_as : param_definition.key
40
50
 
41
51
  if param_definition.sub_definition
42
52
  filter_params(param_definition.sub_definition, params[key])
@@ -24,8 +24,6 @@ module RequestParamsValidation
24
24
  def self.apply_transformation(param, value)
25
25
  transform = param.transform
26
26
 
27
- return value unless transform
28
-
29
27
  transform.respond_to?(:call) ? transform.call(value) : value.send(transform)
30
28
  end
31
29
  end
@@ -12,7 +12,7 @@ module RequestParamsValidation
12
12
  false
13
13
  end
14
14
 
15
- def valid_string?(value)
15
+ def valid_string?(_value)
16
16
  true
17
17
  end
18
18
 
@@ -45,7 +45,7 @@ module RequestParamsValidation
45
45
  validate_format! if param.validate_format?
46
46
  validate_custom_validation! if param.validate_custom_validation?
47
47
 
48
- @value = Params::Converter.apply_transformation(param, value)
48
+ @value
49
49
  end
50
50
 
51
51
  private
@@ -57,7 +57,7 @@ module RequestParamsValidation
57
57
  end
58
58
 
59
59
  def iterate_hash
60
- Params::validate!(param.sub_definition, value) # recursion for the sub_definition
60
+ Params.validate!(param.sub_definition, value) # recursion for the sub_definition
61
61
  end
62
62
 
63
63
  def raise_error(exception_type, options = {})
@@ -5,7 +5,7 @@ module RequestParamsValidation
5
5
  def validate_presence!
6
6
  not_present = param.allow_blank ? value.nil? : value.blank?
7
7
 
8
- raise_error(:on_missing_parameter) if not_present
8
+ raise_error(:on_missing_parameter) if not_present && value != false
9
9
  end
10
10
  end
11
11
  end
@@ -1,3 +1,3 @@
1
1
  module RequestParamsValidation
2
- VERSION = '0.1.1'
2
+ VERSION = '0.4.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: request_params_validation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felipe Fava
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-30 00:00:00.000000000 Z
11
+ date: 2020-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -64,7 +64,7 @@ homepage: https://github.com/felipefava/request_params_validation
64
64
  licenses:
65
65
  - MIT
66
66
  metadata: {}
67
- post_install_message:
67
+ post_install_message:
68
68
  rdoc_options: []
69
69
  require_paths:
70
70
  - lib
@@ -72,16 +72,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: 1.9.3
76
76
  required_rubygems_version: !ruby/object:Gem::Requirement
77
77
  requirements:
78
78
  - - ">="
79
79
  - !ruby/object:Gem::Version
80
80
  version: '0'
81
81
  requirements: []
82
- rubyforge_project:
83
- rubygems_version: 2.7.9
84
- signing_key:
82
+ rubygems_version: 3.0.4
83
+ signing_key:
85
84
  specification_version: 4
86
85
  summary: Validates rails request params
87
86
  test_files: []