rails_simple_params 1.4.0 → 2.0.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +41 -16
  3. data/lib/rails_simple_params/coercion/array_param.rb +1 -1
  4. data/lib/rails_simple_params/coercion/{virtual_param.rb → base.rb} +3 -5
  5. data/lib/rails_simple_params/coercion/big_decimal_param.rb +1 -1
  6. data/lib/rails_simple_params/coercion/boolean_param.rb +1 -1
  7. data/lib/rails_simple_params/coercion/float_param.rb +1 -1
  8. data/lib/rails_simple_params/coercion/hash_param.rb +2 -2
  9. data/lib/rails_simple_params/coercion/integer_param.rb +1 -1
  10. data/lib/rails_simple_params/coercion/string_param.rb +1 -1
  11. data/lib/rails_simple_params/coercion/time_param.rb +2 -2
  12. data/lib/rails_simple_params/coercion.rb +9 -10
  13. data/lib/rails_simple_params/config_check/array_param.rb +18 -0
  14. data/lib/rails_simple_params/config_check/base.rb +82 -0
  15. data/lib/rails_simple_params/config_check/big_decimal_param.rb +17 -0
  16. data/lib/rails_simple_params/config_check/boolean_param.rb +18 -0
  17. data/lib/rails_simple_params/config_check/float_param.rb +17 -0
  18. data/lib/rails_simple_params/config_check/hash_param.rb +18 -0
  19. data/lib/rails_simple_params/config_check/integer_param.rb +17 -0
  20. data/lib/rails_simple_params/config_check/string_param.rb +16 -0
  21. data/lib/rails_simple_params/config_check/time_param.rb +15 -0
  22. data/lib/rails_simple_params/config_check.rb +33 -0
  23. data/lib/rails_simple_params/exceptions.rb +40 -0
  24. data/lib/rails_simple_params/param_evaluator.rb +30 -25
  25. data/lib/rails_simple_params/validator/blank.rb +5 -1
  26. data/lib/rails_simple_params/validator/format.rb +7 -3
  27. data/lib/rails_simple_params/validator/in.rb +12 -7
  28. data/lib/rails_simple_params/validator/is.rb +5 -1
  29. data/lib/rails_simple_params/validator/max.rb +5 -1
  30. data/lib/rails_simple_params/validator/max_length.rb +5 -1
  31. data/lib/rails_simple_params/validator/min.rb +5 -1
  32. data/lib/rails_simple_params/validator/min_length.rb +5 -1
  33. data/lib/rails_simple_params/validator/required.rb +5 -1
  34. data/lib/rails_simple_params/validator.rb +5 -1
  35. data/lib/rails_simple_params/version.rb +1 -1
  36. data/lib/rails_simple_params.rb +4 -1
  37. metadata +14 -4
  38. data/lib/rails_simple_params/invalid_parameter_error.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5d43833fa90c412a87b2c9fbb770b772fa4108bea779f48d26585b5f71cac96
4
- data.tar.gz: 59780a29ba6d6e06cc69129d7c55ec0d7207213e00db452cfa547957b3df9f41
3
+ metadata.gz: ae4ae0e8760be9e443811dce2d53c49cdf6c53fc440a0753d183158fd5d6e2ca
4
+ data.tar.gz: 954ee1b768a922a8a800aec2918fbcd216ba8cba96cf0b04f4b42b666e28534e
5
5
  SHA512:
6
- metadata.gz: e4dcec56bd8a60f7e86c66c44aee6e0f69e632fca2ab77c251421c68f254fbebf23c0d8eb909a2d014af9ca51a2348c24103f19613028c67a0d65522218a3ec6
7
- data.tar.gz: 4d07862e2593a5ffb3567e7cf04203690186c5fba6aaab74bcc4c8b7d1d2f6c5cc8c5283990e2ee912fe7895b4b1c54b9e4d1eae5ba390f4ed62b375fc2c4c3e
6
+ metadata.gz: 685514c6ca2094a649edacd76419b69d8e01cd6a55e2c55fd9a2f09de126d376944ef2021ac796d28ee7c6e079ab8dfad6ac95a000cb01c179d324f0b4e3adf2
7
+ data.tar.gz: 96d9b8b0d0f051b0818b23182c642dd14c2d49c9587511d94f8b3d44faf4e03068b71ae23aea921fddfb2c86c447384534bac20fca329c47d4cfa6ece673a8d4
data/README.md CHANGED
@@ -36,7 +36,30 @@ As usual, in your Gemfile...
36
36
  gem 'rails_simple_params'
37
37
  ```
38
38
 
39
- ## Example
39
+ ### Migrating from `rails_param`
40
+
41
+ Change any code you have rescuing `RailsParam::InvalidParameterError` to instead
42
+ rescue `RailsSimpleParam::InvalidParameter` so you will continue to provide any
43
+ customized HTTP `4xx` responses appropriate for your app.
44
+
45
+ If you want to handle different types of validations separately — especially if
46
+ you want to handle your own I18n translations for the default English error
47
+ messages provided by this gem — you can rescue from any/all of the sub-classed
48
+ exception classes:
49
+
50
+ - `RailsSimpleParam::EmptyParameter`
51
+ - `RailsSimpleParam::InvalidFormat`
52
+ - `RailsSimpleParam::InvalidIdentity`
53
+ - `RailsSimpleParam::InvalidOption`
54
+ - `RailsSimpleParam::InvalidType`
55
+ - `RailsSimpleParam::MissingParameter`
56
+ - `RailsSimpleParam::OutOfRange`
57
+ - `RailsSimpleParam::TooLarge`
58
+ - `RailsSimpleParam::TooLong`
59
+ - `RailsSimpleParam::TooShort`
60
+ - `RailsSimpleParam::TooSmall`
61
+
62
+ ## Using this Gem
40
63
 
41
64
  ``` ruby
42
65
  # GET /search?q=example
@@ -48,6 +71,7 @@ As usual, in your Gemfile...
48
71
  param! :sort, String, default: 'title'
49
72
  param! :order, String, in: %w(asc desc), transform: :downcase, default: 'asc'
50
73
  param! :price, String, format: /[<\=>]\s*\$\d+/
74
+ param! :results, Integer, in: (10..100)
51
75
 
52
76
  # Access the parameters using the params object (e.g. `params[:q]`) as you usually do...
53
77
  end
@@ -66,27 +90,27 @@ are automatically stripped when converting to `BigDecimal`.
66
90
  - `String`
67
91
  - `Integer`
68
92
  - `Float`
69
- - `:boolean/TrueClass/FalseClass` _('1/0', 'true/false', 't/f', 'yes/no', 'y/n')_
70
- - `Array` _('1,2,3,4,5')_
71
- - `Hash` _('key1:value1,key2:value2')_
93
+ - `:boolean/TrueClass/FalseClass` ('1/0', 'true/false', 't/f', 'yes/no', 'y/n')
94
+ - `Array` (e.g. '1,2,3,4,5')
95
+ - `Hash` (e.g. 'key1:value1,key2:value2')
72
96
  - `Date`, `Time`, & `DateTime`
73
- - `BigDecimal` _('$1,000,000')_
97
+ - `BigDecimal` (e.g. '$100,000,000,000')
74
98
 
75
99
  ### Validations
76
100
 
77
101
  Encapsulate business logic in a consistent way with validations. If a parameter
78
102
  does not satisfy a particular condition, an exception
79
- (RailsSimpleParams::InvalidParameterError) is raised. You may use the
80
- [rescue_from][method-rescue-from] method in your controller to catch this kind
81
- of exception.
103
+ (RailsSimpleParams::InvalidParameter or one of its subclasses) is raised. You
104
+ may use the [rescue_from][method-rescue-from] method in your controller to catch
105
+ this kind of exception.
82
106
 
83
- - `required`
84
107
  - `blank`
108
+ - `format`
85
109
  - `is`
86
- - `in`, `within`, `range`
110
+ - `in` (for arrays / ranges / sets)
87
111
  - `min` / `max`
88
112
  - `min_length` / `max_length`
89
- - `format`
113
+ - `required`
90
114
 
91
115
  Customize exception message with option `:message`
92
116
 
@@ -97,11 +121,12 @@ param! :q, String, required: true, message: 'Query not specified'
97
121
  ### Defaults and Transformations
98
122
 
99
123
  Passing a `default` option will provide a default value for a parameter if none
100
- is passed. A `default` can be defined as either a default value or as a `Proc`:
124
+ is passed. A `default` can be defined as either a default value or as a `Proc`
125
+ (and `in` options can also be a `Proc`):
101
126
 
102
127
  ```ruby
103
- param! :attribution, String, default: "©"
104
- param! :year, Integer, default: lambda { Time.now.year }
128
+ param! :attribution, String, default: '©'
129
+ param! :year, Integer, in: lambda { (Time.now.year-5..Time.now.year+5) }, default: lambda { Time.now.year }
105
130
  ```
106
131
 
107
132
  Use the `transform` option to take even more of the business logic of parameter
@@ -155,8 +180,8 @@ end
155
180
  ## Many thanks to:
156
181
 
157
182
  - [Nicolas Blanco](http://twitter.com/nblanco_fr)
158
- - [Mattt Thompson (@mattt)](https://twitter.com/mattt)
159
- - [Vincent Ollivier (@vinc686)](https://twitter.com/vinc686)
183
+ - [Mattt Thompson](https://twitter.com/mattt)
184
+ - [Vincent Ollivier](https://twitter.com/vinc686)
160
185
 
161
186
  ## License
162
187
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RailsSimpleParams
4
4
  class Coercion
5
- class ArrayParam < VirtualParam
5
+ class ArrayParam < Base
6
6
  def coerce
7
7
  return param if param.is_a?(Array)
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RailsSimpleParams
4
4
  class Coercion
5
- class VirtualParam
5
+ class Base
6
6
  attr_reader :param, :options, :type
7
7
 
8
8
  def initialize(param:, options: nil, type: nil)
@@ -13,14 +13,12 @@ module RailsSimpleParams
13
13
  end
14
14
 
15
15
  def coerce
16
- nil
16
+ raise NotImplementedError, "you must implement #coerce in #{self.class.name}"
17
17
  end
18
18
 
19
19
  private
20
20
 
21
- def argument_validation
22
- nil
23
- end
21
+ def argument_validation; end
24
22
  end
25
23
  end
26
24
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RailsSimpleParams
4
4
  class Coercion
5
- class BigDecimalParam < VirtualParam
5
+ class BigDecimalParam < Base
6
6
  DEFAULT_PRECISION = 14
7
7
 
8
8
  def coerce
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RailsSimpleParams
4
4
  class Coercion
5
- class BooleanParam < VirtualParam
5
+ class BooleanParam < Base
6
6
  FALSEY = /^(false|f|no|n|0)$/i
7
7
  TRUTHY = /^(true|t|yes|y|1)$/i
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RailsSimpleParams
4
4
  class Coercion
5
- class FloatParam < VirtualParam
5
+ class FloatParam < Base
6
6
  def coerce
7
7
  return nil if param == '' # e.g. from an empty field in an HTML form
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RailsSimpleParams
4
4
  class Coercion
5
- class HashParam < VirtualParam
5
+ class HashParam < Base
6
6
  def coerce
7
7
  return param if param.is_a?(ActionController::Parameters)
8
8
  raise ArgumentError unless param.respond_to?(:split)
@@ -13,7 +13,7 @@ module RailsSimpleParams
13
13
  private
14
14
 
15
15
  def argument_validation
16
- raise ArgumentError unless type == Hash
16
+ raise InvalidConfiguration unless type == Hash
17
17
  end
18
18
  end
19
19
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RailsSimpleParams
4
4
  class Coercion
5
- class IntegerParam < VirtualParam
5
+ class IntegerParam < Base
6
6
  def coerce
7
7
  return nil if param == '' # e.g. from an empty field in an HTML form
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RailsSimpleParams
4
4
  class Coercion
5
- class StringParam < VirtualParam
5
+ class StringParam < Base
6
6
  def coerce
7
7
  String(param)
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RailsSimpleParams
4
4
  class Coercion
5
- class TimeParam < VirtualParam
5
+ class TimeParam < Base
6
6
  def coerce
7
7
  return nil if param == '' # e.g. from an empty field in an HTML form
8
8
 
@@ -14,7 +14,7 @@ module RailsSimpleParams
14
14
  private
15
15
 
16
16
  def argument_validation
17
- raise ArgumentError unless type.respond_to?(:parse)
17
+ raise InvalidConfiguration unless type.respond_to?(:parse)
18
18
  end
19
19
  end
20
20
  end
@@ -2,8 +2,6 @@
2
2
 
3
3
  module RailsSimpleParams
4
4
  class Coercion
5
- attr_reader :coercion, :param
6
-
7
5
  PARAM_TYPE_MAPPING = {
8
6
  Integer => IntegerParam,
9
7
  Float => FloatParam,
@@ -19,25 +17,26 @@ module RailsSimpleParams
19
17
  boolean: BooleanParam
20
18
  }.freeze
21
19
 
22
- TIME_TYPES = [Date, DateTime, Time].freeze
23
- BOOLEAN_TYPES = [TrueClass, FalseClass, :boolean].freeze
20
+ attr_reader :coercion, :param
24
21
 
25
22
  def initialize(param, type, options)
26
23
  @param = param
27
24
  @coercion = klass_for(type).new(param: param, options: options, type: type)
28
25
  end
29
26
 
27
+ def coerce
28
+ return nil if param.nil?
29
+
30
+ coercion.coerce
31
+ end
32
+
33
+ private
34
+
30
35
  def klass_for(type)
31
36
  klass = PARAM_TYPE_MAPPING[type]
32
37
  return klass if klass
33
38
 
34
39
  raise TypeError
35
40
  end
36
-
37
- def coerce
38
- return nil if param.nil?
39
-
40
- coercion.coerce
41
- end
42
41
  end
43
42
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsSimpleParams
4
+ class ConfigCheck
5
+ class ArrayParam < Base
6
+ private
7
+
8
+ def configuration_validation
9
+ reject :format
10
+ reject :in
11
+ reject :max
12
+ reject :max_length
13
+ reject :min
14
+ reject :min_length
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsSimpleParams
4
+ class ConfigCheck
5
+ class Base
6
+ attr_reader :param, :options, :type
7
+
8
+ def initialize(param:, type:, options: nil)
9
+ @param = param
10
+ @options = options
11
+ @type = type
12
+ configuration_validation
13
+ end
14
+
15
+ private
16
+
17
+ def allowed_list
18
+ return unless (allowed = options[:in])
19
+
20
+ allowed = allowed.call if allowed.respond_to?(:call)
21
+ allowed = [allowed.begin, allowed.end] if allowed.is_a?(Range) && type.is_a?(Numeric)
22
+ allowed
23
+ end
24
+
25
+ def configuration_validation
26
+ raise NotImplementedError, "you must implement #configuration_validation in #{self.class.name}"
27
+ end
28
+
29
+ def raise_error(message)
30
+ raise RailsSimpleParams::InvalidConfiguration.new(message, param:)
31
+ end
32
+
33
+ def reject(key, extra = nil)
34
+ return unless options.key? key
35
+
36
+ raise_error "#{type} param (#{param}) does not allow :#{key}#{extra}"
37
+ end
38
+
39
+ def validate_allowed_options(not_allowed, test_proc)
40
+ return unless (allowed = allowed_list)
41
+
42
+ raise_error ":in on #{param} is not a list" unless allowed.is_a?(Array) || allowed.is_a?(Range)
43
+
44
+ return if allowed.all? { |n| test_proc.call(n) }
45
+
46
+ raise_error "#{type} param (#{param}) does not allow #{not_allowed} :in options"
47
+ end
48
+
49
+ def validate_length(key)
50
+ return unless options.key? key
51
+ return if options[key].is_a? Integer
52
+
53
+ raise_error ":#{key} on #{param} must be an Integer"
54
+ end
55
+
56
+ def validate_lengths
57
+ validate_length :max_length
58
+ validate_length :min_length
59
+ return unless options.key?(:min_length) && options.key?(:max_length)
60
+ return if options[:min_length] < options[:max_length]
61
+
62
+ raise_error ":max_length on #{param} must be larger than :min_length"
63
+ end
64
+
65
+ def validate_limit(key)
66
+ return unless options.key? key
67
+ return if options[key].is_a? Numeric
68
+
69
+ raise_error ":#{key} on #{param} must be a number"
70
+ end
71
+
72
+ def validate_limits
73
+ validate_limit :max
74
+ validate_limit :min
75
+ return unless options.key?(:min) && options.key?(:max)
76
+ return if options[:min] < options[:max]
77
+
78
+ raise_error ":max on #{param} must be larger than :min"
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsSimpleParams
4
+ class ConfigCheck
5
+ class BigDecimalParam < Base
6
+ private
7
+
8
+ def configuration_validation
9
+ reject :format
10
+ reject :in, ' (use :min/:max)'
11
+ reject :max_length
12
+ reject :min_length
13
+ validate_limits
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsSimpleParams
4
+ class ConfigCheck
5
+ class BooleanParam < Base
6
+ private
7
+
8
+ def configuration_validation
9
+ reject :format
10
+ reject :in
11
+ reject :max
12
+ reject :max_length
13
+ reject :min
14
+ reject :min_length
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsSimpleParams
4
+ class ConfigCheck
5
+ class FloatParam < Base
6
+ private
7
+
8
+ def configuration_validation
9
+ reject :format
10
+ reject :max_length
11
+ reject :min_length
12
+ validate_limits
13
+ validate_allowed_options 'non-Numeric', ->(n) { n.is_a?(Numeric) }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsSimpleParams
4
+ class ConfigCheck
5
+ class HashParam < Base
6
+ private
7
+
8
+ def configuration_validation
9
+ reject :format
10
+ reject :in
11
+ reject :max
12
+ reject :max_length
13
+ reject :min
14
+ reject :min_length
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsSimpleParams
4
+ class ConfigCheck
5
+ class IntegerParam < Base
6
+ private
7
+
8
+ def configuration_validation
9
+ reject :format
10
+ reject :max_length
11
+ reject :min_length
12
+ validate_limits
13
+ validate_allowed_options 'non-Integer', ->(n) { n.is_a?(Integer) }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsSimpleParams
4
+ class ConfigCheck
5
+ class StringParam < Base
6
+ private
7
+
8
+ def configuration_validation
9
+ reject :max
10
+ reject :min
11
+ validate_lengths
12
+ validate_allowed_options 'non-String', ->(n) { n.is_a?(String) }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsSimpleParams
4
+ class ConfigCheck
5
+ class TimeParam < Base
6
+ private
7
+
8
+ def configuration_validation
9
+ reject :in
10
+ reject :max_length
11
+ reject :min_length
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsSimpleParams
4
+ class ConfigCheck
5
+ PARAM_TYPE_MAPPING = {
6
+ Integer => IntegerParam,
7
+ Float => FloatParam,
8
+ String => StringParam,
9
+ Array => ArrayParam,
10
+ Hash => HashParam,
11
+ BigDecimal => BigDecimalParam,
12
+ Date => TimeParam,
13
+ DateTime => TimeParam,
14
+ Time => TimeParam,
15
+ TrueClass => BooleanParam,
16
+ FalseClass => BooleanParam,
17
+ boolean: BooleanParam
18
+ }.freeze
19
+
20
+ def initialize(param, type, options)
21
+ klass_for(type).new(param: param, options: options, type: type)
22
+ end
23
+
24
+ private
25
+
26
+ def klass_for(type)
27
+ klass = PARAM_TYPE_MAPPING[type]
28
+ return klass if klass
29
+
30
+ raise TypeError
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsSimpleParams
4
+ class InvalidParameter < StandardError
5
+ attr_accessor :param, :options
6
+
7
+ def initialize(message, param: nil, options: {})
8
+ self.param = param
9
+ self.options = options
10
+ super(message)
11
+ end
12
+
13
+ def message
14
+ return options[:message] if options.is_a?(Hash) && options.key?(:message)
15
+
16
+ super
17
+ end
18
+ end
19
+
20
+ class EmptyParameter < InvalidParameter; end
21
+ class InvalidFormat < InvalidParameter; end
22
+ class InvalidIdentity < InvalidParameter; end
23
+ class InvalidOption < InvalidParameter; end
24
+ class InvalidType < InvalidParameter; end
25
+ class MissingParameter < InvalidParameter; end
26
+ class OutOfRange < InvalidParameter; end
27
+ class TooLarge < InvalidParameter; end
28
+ class TooLong < InvalidParameter; end
29
+ class TooShort < InvalidParameter; end
30
+ class TooSmall < InvalidParameter; end
31
+
32
+ class InvalidConfiguration < StandardError
33
+ attr_accessor :param
34
+
35
+ def initialize(message, param: nil)
36
+ self.param = param
37
+ super(message)
38
+ end
39
+ end
40
+ end
@@ -14,6 +14,7 @@ module RailsSimpleParams
14
14
  return unless params.include?(name) || check_param_presence?(options[:default]) || options[:required]
15
15
 
16
16
  parameter_name = @context ? "#{@context}[#{name}]" : name
17
+ check_config(parameter_name, type, options)
17
18
  coerced_value = coerce(parameter_name, params[name], type, options)
18
19
 
19
20
  parameter = RailsSimpleParams::Parameter.new(
@@ -28,8 +29,8 @@ module RailsSimpleParams
28
29
 
29
30
  # validate presence
30
31
  if params[name].nil? && options[:required]
31
- raise InvalidParameterError.new(
32
- "Parameter #{parameter_name} is required",
32
+ raise MissingParameter.new(
33
+ "#{parameter_name} is required",
33
34
  param: parameter_name,
34
35
  options: options
35
36
  )
@@ -49,6 +50,33 @@ module RailsSimpleParams
49
50
 
50
51
  private
51
52
 
53
+ def coerce(param_name, param, type, options = {})
54
+ return nil if param.nil?
55
+ return param if begin
56
+ param.is_a?(type)
57
+ rescue StandardError
58
+ false
59
+ end
60
+
61
+ Coercion.new(param, type, options).coerce
62
+ rescue ArgumentError, TypeError
63
+ raise InvalidType.new("'#{param}' is not a valid #{type}", param: param_name)
64
+ end
65
+
66
+ def check_config(param_name, type, options = {})
67
+ ConfigCheck.new(param_name, type, options)
68
+ end
69
+
70
+ def check_param_presence?(param)
71
+ !param.nil?
72
+ end
73
+
74
+ def recurse(element, context, index = nil)
75
+ raise InvalidConfiguration.new('no block given', param: element) unless block_given?
76
+
77
+ yield(ParamEvaluator.new(element, context), index)
78
+ end
79
+
52
80
  def recurse_on_parameter(parameter, &) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
53
81
  return if parameter.value.nil?
54
82
 
@@ -65,29 +93,6 @@ module RailsSimpleParams
65
93
  end
66
94
  end
67
95
 
68
- def recurse(element, context, index = nil)
69
- raise InvalidParameterError, 'no block given' unless block_given?
70
-
71
- yield(ParamEvaluator.new(element, context), index)
72
- end
73
-
74
- def check_param_presence?(param)
75
- !param.nil?
76
- end
77
-
78
- def coerce(param_name, param, type, options = {})
79
- return nil if param.nil?
80
- return param if begin
81
- param.is_a?(type)
82
- rescue StandardError
83
- false
84
- end
85
-
86
- Coercion.new(param, type, options).coerce
87
- rescue ArgumentError, TypeError
88
- raise InvalidParameterError.new("'#{param}' is not a valid #{type}", param: param_name)
89
- end
90
-
91
96
  def validate!(param)
92
97
  param.validate
93
98
  end
@@ -19,7 +19,11 @@ module RailsSimpleParams
19
19
  private
20
20
 
21
21
  def error_message
22
- "Parameter #{name} cannot be blank"
22
+ "#{name} cannot be blank"
23
+ end
24
+
25
+ def exception_class
26
+ EmptyParameter
23
27
  end
24
28
  end
25
29
  end
@@ -13,9 +13,13 @@ module RailsSimpleParams
13
13
  private
14
14
 
15
15
  def error_message
16
- return "Parameter #{name} must be a string if using the format validation" unless matches_string_or_time_types?
16
+ return "#{name} must be a string if using the format validation" unless matches_string_or_time_types?
17
17
 
18
- "Parameter #{name} must match format #{options[:format]}" unless string_in_format?
18
+ "#{name} must match format #{options[:format]}" unless string_in_format?
19
+ end
20
+
21
+ def exception_class
22
+ matches_string_or_time_types? ? InvalidFormat : InvalidConfiguration
19
23
  end
20
24
 
21
25
  def matches_time_types?
@@ -27,7 +31,7 @@ module RailsSimpleParams
27
31
  end
28
32
 
29
33
  def string_in_format?
30
- value =~ options[:format] && value.is_a?(String)
34
+ value.is_a?(String) && value =~ options[:format]
31
35
  end
32
36
  end
33
37
  end
@@ -4,18 +4,23 @@ module RailsSimpleParams
4
4
  class Validator
5
5
  class In < Validator
6
6
  def valid_value?
7
- value.nil? || case options[:in]
8
- when Range
9
- options[:in].include?(value)
10
- else
11
- Array(options[:in]).include?(value)
12
- end
7
+ value.nil? || inclusion_group.include?(value)
13
8
  end
14
9
 
15
10
  private
16
11
 
17
12
  def error_message
18
- "Parameter #{parameter.name} must be within #{parameter.options[:in]}"
13
+ "#{parameter.name} must be #{inclusion_group.is_a?(Range) ? 'within' : 'one of'} #{inclusion_group}"
14
+ end
15
+
16
+ def exception_class
17
+ inclusion_group.is_a?(Range) ? OutOfRange : InvalidOption
18
+ end
19
+
20
+ def inclusion_group
21
+ return options[:in].call if options[:in].respond_to?(:call)
22
+
23
+ options[:in]
19
24
  end
20
25
  end
21
26
  end
@@ -10,7 +10,11 @@ module RailsSimpleParams
10
10
  private
11
11
 
12
12
  def error_message
13
- "Parameter #{name} must be #{options[:is]}"
13
+ "#{name} must be #{options[:is]}"
14
+ end
15
+
16
+ def exception_class
17
+ InvalidIdentity
14
18
  end
15
19
  end
16
20
  end
@@ -10,7 +10,11 @@ module RailsSimpleParams
10
10
  private
11
11
 
12
12
  def error_message
13
- "Parameter #{name} cannot be greater than #{options[:max]}"
13
+ "#{name} cannot be greater than #{options[:max]}"
14
+ end
15
+
16
+ def exception_class
17
+ TooLarge
14
18
  end
15
19
  end
16
20
  end
@@ -10,7 +10,11 @@ module RailsSimpleParams
10
10
  private
11
11
 
12
12
  def error_message
13
- "Parameter #{name} cannot have length greater than #{options[:max_length]}"
13
+ "#{name} cannot be longer than #{options[:max_length]} characters"
14
+ end
15
+
16
+ def exception_class
17
+ TooLong
14
18
  end
15
19
  end
16
20
  end
@@ -10,7 +10,11 @@ module RailsSimpleParams
10
10
  private
11
11
 
12
12
  def error_message
13
- "Parameter #{name} cannot be less than #{options[:min]}"
13
+ "#{name} cannot be less than #{options[:min]}"
14
+ end
15
+
16
+ def exception_class
17
+ TooSmall
14
18
  end
15
19
  end
16
20
  end
@@ -10,7 +10,11 @@ module RailsSimpleParams
10
10
  private
11
11
 
12
12
  def error_message
13
- "Parameter #{name} cannot have length less than #{options[:min_length]}"
13
+ "#{name} cannot be shorter than #{options[:min_length]} characters"
14
+ end
15
+
16
+ def exception_class
17
+ TooShort
14
18
  end
15
19
  end
16
20
  end
@@ -10,7 +10,11 @@ module RailsSimpleParams
10
10
  end
11
11
 
12
12
  def error_message
13
- "Parameter #{name} is required"
13
+ "#{name} is required"
14
+ end
15
+
16
+ def exception_class
17
+ MissingParameter
14
18
  end
15
19
  end
16
20
  end
@@ -39,7 +39,7 @@ module RailsSimpleParams
39
39
  def valid!
40
40
  return if valid_value?
41
41
 
42
- raise InvalidParameterError.new(
42
+ raise exception_class.new(
43
43
  error_message,
44
44
  param: name,
45
45
  options: options
@@ -57,6 +57,10 @@ module RailsSimpleParams
57
57
  nil
58
58
  end
59
59
 
60
+ def exception_class
61
+ InvalidParameter
62
+ end
63
+
60
64
  def valid_value?
61
65
  # Should be overwritten in subclass
62
66
  false
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsSimpleParams
4
- VERSION = '1.4.0'
4
+ VERSION = '2.0.0'
5
5
  end
@@ -1,8 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rails_simple_params/param'
4
+ require 'rails_simple_params/config_check/base'
5
+ Dir[File.join(__dir__, 'rails_simple_params/config_check', '*.rb')].each { |file| require file }
4
6
  Dir[File.join(__dir__, 'rails_simple_params/validator', '*.rb')].each { |file| require file }
5
- Dir[File.join(__dir__, 'rails_simple_params/coercion', '*.rb')].reverse_each { |file| require file }
7
+ require 'rails_simple_params/coercion/base'
8
+ Dir[File.join(__dir__, 'rails_simple_params/coercion', '*.rb')].each { |file| require file }
6
9
  Dir[File.join(__dir__, 'rails_simple_params', '*.rb')].each { |file| require file }
7
10
 
8
11
  ActiveSupport.on_load(:action_controller) do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_simple_params
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Weathers
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-13 00:00:00.000000000 Z
10
+ date: 2025-04-17 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: actionpack
@@ -177,6 +177,7 @@ files:
177
177
  - lib/rails_simple_params.rb
178
178
  - lib/rails_simple_params/coercion.rb
179
179
  - lib/rails_simple_params/coercion/array_param.rb
180
+ - lib/rails_simple_params/coercion/base.rb
180
181
  - lib/rails_simple_params/coercion/big_decimal_param.rb
181
182
  - lib/rails_simple_params/coercion/boolean_param.rb
182
183
  - lib/rails_simple_params/coercion/float_param.rb
@@ -184,8 +185,17 @@ files:
184
185
  - lib/rails_simple_params/coercion/integer_param.rb
185
186
  - lib/rails_simple_params/coercion/string_param.rb
186
187
  - lib/rails_simple_params/coercion/time_param.rb
187
- - lib/rails_simple_params/coercion/virtual_param.rb
188
- - lib/rails_simple_params/invalid_parameter_error.rb
188
+ - lib/rails_simple_params/config_check.rb
189
+ - lib/rails_simple_params/config_check/array_param.rb
190
+ - lib/rails_simple_params/config_check/base.rb
191
+ - lib/rails_simple_params/config_check/big_decimal_param.rb
192
+ - lib/rails_simple_params/config_check/boolean_param.rb
193
+ - lib/rails_simple_params/config_check/float_param.rb
194
+ - lib/rails_simple_params/config_check/hash_param.rb
195
+ - lib/rails_simple_params/config_check/integer_param.rb
196
+ - lib/rails_simple_params/config_check/string_param.rb
197
+ - lib/rails_simple_params/config_check/time_param.rb
198
+ - lib/rails_simple_params/exceptions.rb
189
199
  - lib/rails_simple_params/param.rb
190
200
  - lib/rails_simple_params/param_evaluator.rb
191
201
  - lib/rails_simple_params/parameter.rb
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RailsSimpleParams
4
- class InvalidParameterError < StandardError
5
- attr_accessor :param, :options
6
-
7
- def initialize(message, param: nil, options: {})
8
- self.param = param
9
- self.options = options
10
- super(message)
11
- end
12
-
13
- def message
14
- return options[:message] if options.is_a?(Hash) && options.key?(:message)
15
-
16
- super
17
- end
18
- end
19
- end