instance method
permit
Ruby on Rails edge
Since v4.0.13Signature
permit(*filters)
Returns a new ActionController::Parameters instance that includes only the
given `filters` and sets the `permitted` attribute for the object to `true`.
This is useful for limiting which attributes should be allowed for mass
updating.
params = ActionController::Parameters.new(name: "Francesco", age: 22, role: "admin")
permitted = params.permit(:name, :age)
permitted.permitted? # => true
permitted.has_key?(:name) # => true
permitted.has_key?(:age) # => true
permitted.has_key?(:role) # => false
Only permitted scalars pass the filter. For example, given
params.permit(:name)
`:name` passes if it is a key of `params` whose associated value is of type
`String`, `Symbol`, `NilClass`, `Numeric`, `TrueClass`, `FalseClass`, `Date`,
`Time`, `DateTime`, `StringIO`, `IO`, ActionDispatch::Http::UploadedFile or
`Rack::Test::UploadedFile`. Otherwise, the key `:name` is filtered out.
You may declare that the parameter should be an array of permitted scalars by
mapping it to an empty array:
params = ActionController::Parameters.new(tags: ["rails", "parameters"])
params.permit(tags: [])
Sometimes it is not possible or convenient to declare the valid keys of a hash
parameter or its internal structure. Just map to an empty hash:
params.permit(preferences: {})
Be careful because this opens the door to arbitrary input. In this case,
`permit` ensures values in the returned structure are permitted scalars and
filters out anything else.
You can also use `permit` on nested parameters:
params = ActionController::Parameters.new({
person: {
name: "Francesco",
age: 22,
pets: [{
name: "Purplish",
category: "dogs"
}]
}
})
permitted = params.permit(person: [ :name, { pets: :name } ])
permitted.permitted? # => true
permitted[:person][:name] # => "Francesco"
permitted[:person][:age] # => nil
permitted[:person][:pets][0][:name] # => "Purplish"
permitted[:person][:pets][0][:category] # => nil
This has the added benefit of rejecting user-modified inputs that send a
string when a hash is expected.
When followed by `require`, you can both filter and require parameters
following the typical pattern of a Rails form. The `expect` method was
made specifically for this use case and is the recommended way to require
and permit parameters.
permitted = params.expect(person: [:name, :age])
When using `permit` and `require` separately, pay careful attention to the
order of the method calls.
params = ActionController::Parameters.new(person: { name: "Martin", age: 40, role: "admin" })
permitted = params.permit(person: [:name, :age]).require(:person) # correct
When require is used first, it is possible for users of your application to
trigger a NoMethodError when the user, for example, sends a string for :person.
params = ActionController::Parameters.new(person: "tampered")
permitted = params.require(:person).permit(:name, :age) # not recommended
# => NoMethodError: undefined method `permit' for an instance of String
Note that if you use `permit` in a key that points to a hash, it won't allow
all the hash. You also need to specify which attributes inside the hash should
be permitted.
params = ActionController::Parameters.new({
person: {
contact: {
email: "none@test.com",
phone: "555-1234"
}
}
})
params.permit(person: :contact).require(:person)
# => ActionController::ParameterMissing: param is missing or the value is empty or invalid: person
params.permit(person: { contact: :phone }).require(:person)
# => #<ActionController::Parameters {"contact"=>#<ActionController::Parameters {"phone"=>"555-1234"} permitted: true>} permitted: true>
params.permit(person: { contact: [ :email, :phone ] }).require(:person)
# => #<ActionController::Parameters {"contact"=>#<ActionController::Parameters {"email"=>"none@test.com", "phone"=>"555-1234"} permitted: true>} permitted: true>
If your parameters specify multiple parameters indexed by a number, you can
permit each set of parameters under the numeric key to be the same using the
same syntax as permitting a single item.
params = ActionController::Parameters.new({
person: {
'0': {
email: "none@test.com",
phone: "555-1234"
},
'1': {
email: "nothing@test.com",
phone: "555-6789"
},
}
})
params.permit(person: [:email]).to_h
# => {"person"=>{"0"=>{"email"=>"none@test.com"}, "1"=>{"email"=>"nothing@test.com"}}}
If you want to specify what keys you want from each numeric key, you can
instead specify each one individually
params = ActionController::Parameters.new({
person: {
'0': {
email: "none@test.com",
phone: "555-1234"
},
'1': {
email: "nothing@test.com",
phone: "555-6789"
},
}
})
params.permit(person: { '0': [:email], '1': [:phone]}).to_h
# => {"person"=>{"0"=>{"email"=>"none@test.com"}, "1"=>{"phone"=>"555-6789"}}}
: (*untyped) -> self
Parameters
-
filtersrest
Source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 683
def permit(*filters)
permit_filters(filters, on_unpermitted: self.class.action_on_unpermitted_parameters, explicit_arrays: false)
end
Defined in actionpack/lib/action_controller/metal/strong_parameters.rb line 683
· View on GitHub
· Improve this page
· Find usages on GitHub
Defined in ActionController::Parameters