@@ -13,24 +13,44 @@ class InvalidParameterError < StandardError
1313
1414 def param ( name , type , options = { } )
1515 name = name . to_s
16+ applicable_params = @applicable_params || params
1617
17- return unless params . member? ( name ) or options [ :default ] or options [ :required ]
18+ return unless applicable_params . member? ( name ) or options [ :default ] or options [ :required ]
1819
1920 begin
20- params [ name ] = coerce ( params [ name ] , type , options )
21- params [ name ] = ( options [ :default ] . call if options [ :default ] . respond_to? ( :call ) ) || options [ :default ] if params [ name ] . nil? and options [ :default ]
22- params [ name ] = options [ :transform ] . to_proc . call ( params [ name ] ) if params [ name ] and options [ :transform ]
23- validate! ( params [ name ] , options )
21+ applicable_params [ name ] = coerce ( applicable_params [ name ] , type , options )
22+ applicable_params [ name ] = ( options [ :default ] . call if options [ :default ] . respond_to? ( :call ) ) || options [ :default ] if applicable_params [ name ] . nil? and options [ :default ]
23+ applicable_params [ name ] = options [ :transform ] . to_proc . call ( applicable_params [ name ] ) if applicable_params [ name ] and options [ :transform ]
24+ validate! ( applicable_params [ name ] , options )
25+
26+
27+ if block_given?
28+ if type != Hash
29+ raise Sinatra ::Param ::InvalidParameterError . new (
30+ 'Only the Hash parameter validation can use sub hash validation method' )
31+ end
32+ original_applicable_params = @applicable_params
33+ original_parent_key_name = @parent_key_name
34+ @applicable_params = applicable_params [ name ]
35+ @parent_key_name = formatted_params ( @parent_key_name , name )
36+
37+ yield
38+
39+ @applicable_params = original_applicable_params
40+ @parent_key_name = original_parent_key_name
41+ end
2442 rescue InvalidParameterError => exception
43+ exception_name = formatted_params ( @parent_key_name , name )
2544 if options [ :raise ] or ( settings . raise_sinatra_param_exceptions rescue false )
26- exception . param , exception . options = name , options
45+ exception . param = exception_name
46+ exception . options = options
2747 raise exception
2848 end
2949
3050 error = exception . to_s
3151
3252 if content_type and content_type . match ( mime_type ( :json ) )
33- error = { message : error , errors : { name => exception . message } } . to_json
53+ error = { message : error , errors : { exception_name => exception . message } } . to_json
3454 end
3555
3656 halt 400 , error
@@ -40,18 +60,19 @@ def param(name, type, options = {})
4060 def one_of ( *args )
4161 options = args . last . is_a? ( Hash ) ? args . pop : { }
4262 names = args . collect ( &:to_s )
63+ applicable_params = @applicable_params || params
4364
4465 return unless names . length >= 2
4566
4667 begin
47- validate_one_of! ( params , names , options )
68+ validate_one_of! ( applicable_params , names , options )
4869 rescue InvalidParameterError => exception
4970 if options [ :raise ] or ( settings . raise_sinatra_param_exceptions rescue false )
5071 exception . param , exception . options = names , options
5172 raise exception
5273 end
5374
54- error = "Invalid parameters [ #{ names . join ( ', ' ) } ] "
75+ error = "Invalid parameters #{ formatted_params ( @parent_key_name , names ) } "
5576 if content_type and content_type . match ( mime_type ( :json ) )
5677 error = { message : error , errors : { names => exception . message } } . to_json
5778 end
@@ -63,20 +84,22 @@ def one_of(*args)
6384 def any_of ( *args )
6485 options = args . last . is_a? ( Hash ) ? args . pop : { }
6586 names = args . collect ( &:to_s )
87+ applicable_params = @applicable_params || params
6688
6789 return unless names . length >= 2
6890
6991 begin
70- validate_any_of! ( params , names , options )
92+ validate_any_of! ( applicable_params , names , options )
7193 rescue InvalidParameterError => exception
7294 if options [ :raise ] or ( settings . raise_sinatra_param_exceptions rescue false )
7395 exception . param , exception . options = names , options
7496 raise exception
7597 end
7698
77- error = "Invalid parameters [#{ names . join ( ', ' ) } ]"
99+ formatted_params = formatted_params ( @parent_key_name , names )
100+ error = "Invalid parameters #{ formatted_params } "
78101 if content_type and content_type . match ( mime_type ( :json ) )
79- error = { message : error , errors : { names => exception . message } } . to_json
102+ error = { message : error , errors : { formatted_params => exception . message } } . to_json
80103 end
81104
82105 halt 400 , error
@@ -143,11 +166,15 @@ def validate!(param, options)
143166 end
144167
145168 def validate_one_of! ( params , names , options )
146- raise InvalidParameterError , "Only one of [#{ names . join ( ', ' ) } ] is allowed" if names . count { |name | present? ( params [ name ] ) } > 1
169+ if names . count { |name | present? ( params [ name ] ) } > 1
170+ raise InvalidParameterError , "Only one of #{ formatted_params ( @parent_key_name , names ) } is allowed"
171+ end
147172 end
148173
149174 def validate_any_of! ( params , names , options )
150- raise InvalidParameterError , "One of parameters [#{ names . join ( ', ' ) } ] is required" if names . count { |name | present? ( params [ name ] ) } < 1
175+ if names . count { |name | present? ( params [ name ] ) } < 1
176+ raise InvalidParameterError , "One of parameters #{ formatted_params ( @parent_key_name , names ) } is required"
177+ end
151178 end
152179
153180 # ActiveSupport #present? and #blank? without patching Object
@@ -158,6 +185,14 @@ def present?(object)
158185 def blank? ( object )
159186 object . respond_to? ( :empty? ) ? object . empty? : !object
160187 end
188+
189+ def formatted_params ( parent_key , name )
190+ if name . is_a? ( Array )
191+ name = "[#{ name . join ( ', ' ) } ]"
192+ end
193+
194+ return parent_key ? "#{ parent_key } [#{ name } ]" : name
195+ end
161196 end
162197
163198 helpers Param
0 commit comments