Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implements require with multiple parameters

Normal use is unchanged.

When used with multiple parameters the error raised in case a
parameter is missing lists all the missing parameters.

Returns the params hash if no required parameters are missing.
  • Loading branch information...
commit 7758a3446879f27b1932eef81adb116659266218 1 parent c789f57
Jonas Schubert Erlandsson authored
View
10 README.md
@@ -70,6 +70,16 @@ This declaration whitelists the `name`, `emails` and `friends` attributes. It is
Thanks to Nick Kallen for the permit idea!
+## Requiring multiple values
+
+In some cases you might want to require several parameters to be present before proceeding, such as for an API where the params might be a flat hash. You can use `require` to do this:
+
+``` ruby
+params.require(:username, :password).permit(:version)
+```
+
+When used with multiple inputs `require` raises a `ActionController::MissingParameter` error with *all* the missing attributes specified in the message. If no values are missing the params hash is returned unmodified.
+
## Handling of Unpermitted Keys
By default parameter keys that are not explicitly permitted will be logged in the development and test environment. In other environments these parameters will simply be filtered out and ignored.
View
29 lib/action_controller/parameters.rb
@@ -22,7 +22,7 @@ class UnpermittedParameters < IndexError
def initialize(params)
@params = params
- super("found unpermitted parameters: #{params.join(", ")}")
+ super("found unpermitted parameter(s): #{params.join(", ")}")
end
end
@@ -51,8 +51,12 @@ def permit!
self
end
- def require(key)
- self[key].presence || raise(ActionController::ParameterMissing.new(key))
+ def require(*keys)
+ if keys.many?
+ require_multiple(keys)
+ else
+ require_single(keys)
+ end
end
alias :required :require
@@ -98,6 +102,20 @@ def dup
end
protected
+ def require_single(keys)
+ key = keys.first
+ self[key].presence || raise(ActionController::ParameterMissing.new(key))
+ end
+
+ def require_multiple(keys)
+ missing_keys = keys.select do |key|
+ self[key].blank?
+ end
+
+ raise(ActionController::ParameterMissing.new(missing_keys.join(', '))) if missing_keys.compact.any?
+ self
+ end
+
def convert_value(value)
if value.class == Hash
self.class.new_from_hash_copying_default(value)
@@ -109,7 +127,6 @@ def convert_value(value)
end
private
-
def convert_hashes_to_parameters(key, value)
if value.is_a?(Parameters) || !value.is_a?(Hash)
value
@@ -217,7 +234,7 @@ def unpermitted_parameters!(params)
unpermitted_keys = unpermitted_keys(params)
if unpermitted_keys.any?
- case self.class.action_on_unpermitted_parameters
+ case self.class.action_on_unpermitted_parameters
when :log
name = "unpermitted_parameters.action_controller"
ActiveSupport::Notifications.instrument(name, :keys => unpermitted_keys)
@@ -237,7 +254,7 @@ module StrongParameters
included do
rescue_from(ActionController::ParameterMissing) do |parameter_missing_exception|
- render :text => "Required parameter missing: #{parameter_missing_exception.param}", :status => :bad_request
+ render :text => "Required parameter(s) missing: #{parameter_missing_exception.param}", :status => :bad_request
end
end
View
2  test/action_controller_required_params_test.rb
@@ -25,6 +25,6 @@ class ActionControllerRequiredParamsTest < ActionController::TestCase
test "missing parameters will be mentioned in the return" do
post :create, { :magazine => { :name => "Mjallo!" } }
- assert_equal "Required parameter missing: book", response.body
+ assert_match "book", response.body
end
end
View
4 test/log_on_unpermitted_params_test.rb
@@ -16,7 +16,7 @@ def teardown
:fishing => "Turnips"
})
- assert_logged("Unpermitted parameters: fishing") do
+ assert_logged("Unpermitted parameter(s): fishing") do
params.permit(:book => [:pages])
end
end
@@ -26,7 +26,7 @@ def teardown
:book => { :pages => 65, :title => "Green Cats and where to find then." }
})
- assert_logged("Unpermitted parameters: title") do
+ assert_logged("Unpermitted parameter(s): title") do
params.permit(:book => [:pages])
end
end
View
25 test/parameters_require_test.rb
@@ -7,4 +7,29 @@ class ParametersRequireTest < ActiveSupport::TestCase
ActionController::Parameters.new(:person => {}).require(:person)
end
end
+
+ test "permit multiple required parameters" do
+ params = ActionController::Parameters.new(:username => 'user', :password => '<3<3<3<3')
+ assert_nothing_raised(ActionController::ParameterMissing) do
+ params.require(:username, :password)
+ end
+
+ assert params.has_key?(:username)
+ assert params.has_key?(:password)
+ end
+
+ test "multiple required parameters must be present not merely not nil" do
+ params = ActionController::Parameters.new(:username => '', :password => nil)
+ assert_raises(ActionController::ParameterMissing) do
+ params.require(:username, :password)
+ end
+ end
+
+ test "all parameters are returned after required with multiple parameters" do
+ params = ActionController::Parameters.new(:username => 'user', :password => '<3<3<3<3', :version => 1)
+
+ params.require(:username, :password)
+
+ assert params.has_key?(:version)
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.