@@ -13,24 +13,39 @@ 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+ if block_given?
27+ original_applicable_params = @applicable_params
28+ original_parent_key_name = @parent_key_name
29+ @applicable_params = applicable_params [ name ]
30+ @parent_key_name = formatted_params ( @parent_key_name , name )
31+
32+ yield
33+
34+ @applicable_params = original_applicable_params
35+ @parent_key_name = original_parent_key_name
36+ end
2437 rescue InvalidParameterError => exception
38+ exception_name = formatted_params ( @parent_key_name , name )
2539 if options [ :raise ] or ( settings . raise_sinatra_param_exceptions rescue false )
26- exception . param , exception . options = name , options
40+ exception . param = exception_name
41+ exception . options = options
2742 raise exception
2843 end
2944
3045 error = exception . to_s
3146
3247 if content_type and content_type . match ( mime_type ( :json ) )
33- error = { message : error , errors : { name => exception . message } } . to_json
48+ error = { message : error , errors : { exception_name => exception . message } } . to_json
3449 end
3550
3651 halt 400 , error
@@ -40,18 +55,19 @@ def param(name, type, options = {})
4055 def one_of ( *args )
4156 options = args . last . is_a? ( Hash ) ? args . pop : { }
4257 names = args . collect ( &:to_s )
58+ applicable_params = @applicable_params || params
4359
4460 return unless names . length >= 2
4561
4662 begin
47- validate_one_of! ( params , names , options )
63+ validate_one_of! ( applicable_params , names , options )
4864 rescue InvalidParameterError => exception
4965 if options [ :raise ] or ( settings . raise_sinatra_param_exceptions rescue false )
5066 exception . param , exception . options = names , options
5167 raise exception
5268 end
5369
54- error = "Invalid parameters [ #{ names . join ( ', ' ) } ] "
70+ error = "Invalid parameters #{ formatted_params ( @parent_key_name , names ) } "
5571 if content_type and content_type . match ( mime_type ( :json ) )
5672 error = { message : error , errors : { names => exception . message } } . to_json
5773 end
@@ -63,20 +79,22 @@ def one_of(*args)
6379 def any_of ( *args )
6480 options = args . last . is_a? ( Hash ) ? args . pop : { }
6581 names = args . collect ( &:to_s )
82+ applicable_params = @applicable_params || params
6683
6784 return unless names . length >= 2
6885
6986 begin
70- validate_any_of! ( params , names , options )
87+ validate_any_of! ( applicable_params , names , options )
7188 rescue InvalidParameterError => exception
7289 if options [ :raise ] or ( settings . raise_sinatra_param_exceptions rescue false )
7390 exception . param , exception . options = names , options
7491 raise exception
7592 end
7693
77- error = "Invalid parameters [#{ names . join ( ', ' ) } ]"
94+ formatted_params = formatted_params ( @parent_key_name , names )
95+ error = "Invalid parameters #{ formatted_params } "
7896 if content_type and content_type . match ( mime_type ( :json ) )
79- error = { message : error , errors : { names => exception . message } } . to_json
97+ error = { message : error , errors : { formatted_params => exception . message } } . to_json
8098 end
8199
82100 halt 400 , error
@@ -143,11 +161,15 @@ def validate!(param, options)
143161 end
144162
145163 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
164+ if names . count { |name | present? ( params [ name ] ) } > 1
165+ raise InvalidParameterError , "Only one of #{ formatted_params ( @parent_key_name , names ) } is allowed"
166+ end
147167 end
148168
149169 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
170+ if names . count { |name | present? ( params [ name ] ) } < 1
171+ raise InvalidParameterError , "One of parameters #{ formatted_params ( @parent_key_name , names ) } is required"
172+ end
151173 end
152174
153175 # ActiveSupport #present? and #blank? without patching Object
@@ -158,6 +180,14 @@ def present?(object)
158180 def blank? ( object )
159181 object . respond_to? ( :empty? ) ? object . empty? : !object
160182 end
183+
184+ def formatted_params ( parent_key , name )
185+ if name . is_a? ( Array )
186+ name = "[#{ name . join ( ', ' ) } ]"
187+ end
188+
189+ return parent_key ? "#{ parent_key } [#{ name } ]" : name
190+ end
161191 end
162192
163193 helpers Param
0 commit comments