Class: ActionController::Parameters
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
|
|
Instance Chain:
|
|
Inherits: |
ActiveSupport::HashWithIndifferentAccess
|
Defined in: | actionpack/lib/action_controller/metal/strong_parameters.rb |
Overview
Allows to choose which attributes should be whitelisted for mass updating and thus prevent accidentally exposing that which shouldn't be exposed. Provides two methods for this purpose: #require and #permit. The former is used to mark parameters as required. The latter is used to set the parameter as permitted and limit which attributes should be allowed for mass updating.
params = ActionController::Parameters.new({
person: {
name: 'Francesco',
age: 22,
role: 'admin'
}
})
permitted = params.require(:person).permit(:name, :age)
permitted # => {"name"=>"Francesco", "age"=>22}
permitted.class # => ActionController::Parameters
permitted.permitted? # => true
Person.first.update!(permitted)
# => #<Person id: 1, name: "Francesco", age: 22, role: "user">
It provides two options that controls the top-level behavior of new instances:
-
.permit_all_parameters - If it's
true
, all the parameters will be permitted by default. The default isfalse
. -
.action_on_unpermitted_parameters - Allow to control the behavior when parameters that are not explicitly permitted are found. The values can be
:log
to write a message on the logger or:raise
to raise ActionController::UnpermittedParameters exception. The default value is:log
in test and development environments,false
otherwise.
Examples:
params = ActionController::Parameters.new
params.permitted? # => false
ActionController::Parameters.permit_all_parameters = true
params = ActionController::Parameters.new
params.permitted? # => true
params = ActionController::Parameters.new(a: "123", b: "456")
params.permit(:c)
# => {}
ActionController::Parameters.action_on_unpermitted_parameters = :raise
params = ActionController::Parameters.new(a: "123", b: "456")
params.permit(:c)
# => ActionController::UnpermittedParameters: found unpermitted keys: a, b
Please note that these options *are not thread-safe*. In a multi-threaded environment they should only be set once at boot-time and never mutated at runtime.
Parameters
inherits from ::ActiveSupport::HashWithIndifferentAccess, this means that you can fetch values using either :key
or "key"
.
params = ActionController::Parameters.new(key: 'value')
params[:key] # => "value"
params["key"] # => "value"
Constant Summary
-
EMPTY_ARRAY =
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 561[]
-
PERMITTED_SCALAR_TYPES =
This is a white list of permitted scalar types that includes the ones supported in XML and JSON requests.
This list is in particular used to filter ordinary requests, ::String goes as first element to quickly short-circuit the common case.
If you modify this collection please update the API of #permit above.
[ String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, # DateTimes are Dates, we document the type but avoid the redundant check. StringIO, IO, ActionDispatch::Http::UploadedFile, Rack::Test::UploadedFile, ]
Class Attribute Summary
- .action_on_unpermitted_parameters rw
-
.always_permitted_parameters
(also: #always_permitted_parameters)
rw
By default, never raise an UnpermittedParameters exception if these params are present.
- .permit_all_parameters rw
Class Method Summary
- .const_missing(const_name)
-
.new(attributes = nil) ⇒ Parameters
constructor
Returns a new instance of
Parameters
.
::ActiveSupport::HashWithIndifferentAccess - Inherited
::Hash - Inherited
.from_trusted_xml | Builds a ::Hash from XML just like Hash.from_xml, but also allows ::Symbol and YAML. |
.from_xml | Returns a ::Hash containing a collection of pairs when the key is the node name and the value is its content. |
Instance Attribute Summary
- #always_permitted_parameters rw
-
#permitted? ⇒ Boolean
readonly
Returns
true
if the parameter is permitted,false
otherwise.
::ActiveSupport::HashWithIndifferentAccess - Inherited
#extractable_options? | Returns |
::Hash - Inherited
#extractable_options? | By default, only instances of ::Hash itself are extractable. |
Instance Method Summary
-
#[](key)
Returns a parameter for the given
key
. -
#converted_arrays
Attribute that keeps track of converted arrays, if any, to avoid double looping in the common use case permit + mass-assignment.
-
#delete(key, &block)
Deletes and returns a key-value pair from
Parameters
whose key is equal to key. -
#dup
Returns an exact copy of the
Parameters
instance. -
#each(&block)
Alias for #each_pair.
-
#each_pair(&block)
(also: #each)
Convert all hashes in values into parameters, then yield each pair like the same way as
Hash#each_pair
-
#extract!(*keys)
Removes and returns the key/value pairs matching the given keys.
-
#fetch(key, *args)
Returns a parameter for the given
key
. -
#permit(*filters)
Returns a new
Parameters
instance that includes only the givenfilters
and sets thepermitted
attribute for the object totrue
. -
#permit!
Sets the
permitted
attribute totrue
. -
#require(key)
(also: #required)
Ensures that a parameter is present.
-
#required(key)
Alias for #require.
-
#select!(&block)
Equivalent to
Hash#keep_if
, but returns nil if no changes were made. -
#slice(*keys)
Returns a new
Parameters
instance that includes only the givenkeys
. -
#to_h
Returns a safe ::Hash representation of this parameter with all unpermitted keys removed.
-
#to_unsafe_h
(also: #to_unsafe_hash)
Returns an unsafe, unfiltered ::Hash representation of this parameter.
-
#to_unsafe_hash
Alias for #to_unsafe_h.
-
#transform_values
Returns a new
Parameters
with the results of runningblock
once for every value.
::ActiveSupport::HashWithIndifferentAccess - Inherited
#[]= | Assigns a new value to the hash: |
#compact, #deep_stringify_keys, #deep_stringify_keys!, #deep_symbolize_keys, #default, | |
#delete | Removes the specified key from the hash. |
#dup | Returns a shallow copy of the hash. |
#fetch | Same as |
#has_key? | |
#include? | |
#key? | Checks the hash for a key matching the argument passed in: |
#member? | |
#merge | This method has the same semantics of |
#merge! | |
#nested_under_indifferent_access, #regular_update, #regular_writer, #reject, | |
#replace | Replaces the contents of this hash with other_hash. |
#reverse_merge | Like |
#reverse_merge! | Same semantics as |
#select, | |
#store | Alias for ActiveSupport::HashWithIndifferentAccess#[]=. |
#stringify_keys, #stringify_keys!, #symbolize_keys, | |
#to_hash | Convert to a regular hash with string keys. |
#to_options!, #transform_values, | |
#update | Updates the receiver in-place, merging in the hash passed as argument: |
#values_at | Returns an array of the values at the specified indices: |
#with_indifferent_access |
::Hash - Inherited
#assert_valid_keys | Validate all keys in a hash match |
#blank? | A hash is blank if it's empty: |
#compact | Returns a hash with non |
#compact! | Replaces current hash with non |
#deep_dup | Returns a deep copy of hash. |
#deep_merge | Returns a new hash with |
#deep_merge! | Same as |
#deep_stringify_keys | Returns a new hash with all keys converted to strings. |
#deep_stringify_keys! | Destructively convert all keys to strings. |
#deep_symbolize_keys | Returns a new hash with all keys converted to symbols, as long as they respond to |
#deep_symbolize_keys! | Destructively convert all keys to symbols, as long as they respond to |
#deep_transform_keys | Returns a new hash with all keys converted by the block operation. |
#deep_transform_keys! | Destructively convert all keys by using the block operation. |
#except | Returns a hash that includes everything but the given keys. |
#except! | Replaces the hash without the given keys. |
#extract! | Removes and returns the key/value pairs matching the given keys. |
#nested_under_indifferent_access | Alias for Hash#with_indifferent_access. |
#reverse_merge | Merges the caller into |
#reverse_merge! | Destructive |
#reverse_update | Alias for Hash#reverse_merge!. |
#slice | Slice a hash to include only the given keys. |
#slice! | Replaces the hash with only the given keys. |
#stringify_keys | Returns a new hash with all keys converted to strings. |
#stringify_keys! | Destructively convert all keys to strings. |
#symbolize_keys | Returns a new hash with all keys converted to symbols, as long as they respond to |
#symbolize_keys! | Destructively convert all keys to symbols, as long as they respond to |
#to_options | Alias for Hash#symbolize_keys. |
#to_options! | Alias for Hash#symbolize_keys!. |
#to_param | Alias for Hash#to_query. |
#to_query | Returns a string representation of the receiver suitable for use as a URL query string: |
#to_xml | Returns a string containing an XML representation of its receiver: |
#transform_keys | Returns a new hash with all keys converted using the block operation. |
#transform_keys! | Destructively convert all keys using the block operations. |
#transform_values | Returns a new hash with the results of running |
#transform_values! | Destructive #transform_values |
#with_indifferent_access | Returns an ::ActiveSupport::HashWithIndifferentAccess out of its receiver: |
Constructor Details
.new(attributes = nil) ⇒ Parameters
Returns a new instance of Parameters
. Also, sets the permitted
attribute to the default value of .permit_all_parameters.
class Person < ActiveRecord::Base
end
params = ActionController::Parameters.new(name: 'Francesco')
params.permitted? # => false
Person.new(params) # => ActiveModel::ForbiddenAttributesError
ActionController::Parameters.permit_all_parameters = true
params = ActionController::Parameters.new(name: 'Francesco')
params.permitted? # => true
Person.new(params) # => #<Person id: nil, name: "Francesco">
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 148
def initialize(attributes = nil) super(attributes) @permitted = self.class.permit_all_parameters end
Class Attribute Details
.action_on_unpermitted_parameters (rw)
[ GitHub ]# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 110
cattr_accessor :action_on_unpermitted_parameters, instance_accessor: false
.always_permitted_parameters (rw) Also known as: #always_permitted_parameters
By default, never raise an UnpermittedParameters exception if these params are present. The default includes both 'controller' and 'action' because they are added by ::Rails and should be of no concern. One way to change these is to specify always_permitted_parameters
in your config. For instance:
config.always_permitted_parameters = %w( controller action format )
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 119
cattr_accessor :always_permitted_parameters
.permit_all_parameters (rw)
[ GitHub ]# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 109
cattr_accessor :permit_all_parameters, instance_accessor: false
Class Method Details
.const_missing(const_name)
[ GitHub ]# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 122
def self.const_missing(const_name) super unless const_name == :NEVER_UNPERMITTED_PARAMS ActiveSupport::Deprecation.warn(<<-MSG.squish) `ActionController::Parameters::NEVER_UNPERMITTED_PARAMS` has been deprecated. Use `ActionController::Parameters.always_permitted_parameters` instead. MSG always_permitted_parameters end
Instance Attribute Details
#always_permitted_parameters (rw)
[ GitHub ]# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 119
cattr_accessor :always_permitted_parameters
#permitted? ⇒ Boolean
(rw)
Returns true
if the parameter is permitted, false
otherwise.
params = ActionController::Parameters.new
params.permitted? # => false
params.permit!
params.permitted? # => true
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 207
def permitted? @permitted end
Instance Method Details
#[](key)
Returns a parameter for the given key
. If not found, returns nil
.
params = ActionController::Parameters.new(person: { name: 'Francesco' })
params[:person] # => {"name"=>"Francesco"}
params[:none] # => nil
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 350
def [](key) convert_hashes_to_parameters(key, super) end
#converted_arrays
Attribute that keeps track of converted arrays, if any, to avoid double looping in the common use case permit + mass-assignment. Defined in a method to instantiate it only if needed.
Testing membership still loops, but it's going to be faster than our own loop that converts values. Also, we are not going to build a new array object per fetch.
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 197
def converted_arrays @converted_arrays ||= Set.new end
#delete(key, &block)
Deletes and returns a key-value pair from Parameters
whose key is equal to key. If the key is not found, returns the default value. If the optional code block is given and the key is not found, pass in the key and return the result of block.
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 420
def delete(key, &block) convert_hashes_to_parameters(key, super, false) end
#dup
Returns an exact copy of the Parameters
instance. permitted
state is kept on the duped object.
params = ActionController::Parameters.new(a: 1)
params.permit!
params.permitted? # => true
copy_params = params.dup # => {"a"=>1}
copy_params.permitted? # => true
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 437
def dup super.tap do |duplicate| duplicate.permitted = @permitted end end
#each(&block)
Alias for #each_pair.
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 188
alias_method :each, :each_pair
#each_pair(&block) Also known as: #each
Convert all hashes in values into parameters, then yield each pair like the same way as Hash#each_pair
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 180
def each_pair(&block) super do |key, value| convert_hashes_to_parameters(key, value) end super end
#extract!(*keys)
Removes and returns the key/value pairs matching the given keys.
params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
params.extract!(:a, :b) # => {"a"=>1, "b"=>2}
params # => {"c"=>3}
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 387
def extract!(*keys) new_instance_with_inherited_permitted_status(super) end
#fetch(key, *args)
Returns a parameter for the given key
. If the key
can't be found, there are several options: With no other arguments, it will raise an ParameterMissing error; if more arguments are given, then that will be returned; if a block is given, then that will be run and its result returned.
params = ActionController::Parameters.new(person: { name: 'Francesco' })
params.fetch(:person) # => {"name"=>"Francesco"}
params.fetch(:none) # => ActionController::ParameterMissing: param not found: none
params.fetch(:none, 'Francesco') # => "Francesco"
params.fetch(:none) { 'Francesco' } # => "Francesco"
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 365
def fetch(key, *args) convert_hashes_to_parameters(key, super, false) rescue KeyError raise ActionController::ParameterMissing.new(key) end
#permit(*filters)
Returns a new 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(user: { name: 'Francesco', age: 22, role: 'admin' })
permitted = params.require(:user).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 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: [])
You can also use permit
on nested parameters, like:
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
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 whitelisted.
params = ActionController::Parameters.new({
person: {
contact: {
email: 'none@test.com',
phone: '555-1234'
}
}
})
params.require(:person).permit(:contact)
# => {}
params.require(:person).permit(contact: :phone)
# => {"contact"=>{"phone"=>"555-1234"}}
params.require(:person).permit(contact: [ :email, :phone ])
# => {"contact"=>{"email"=>"none@test.com", "phone"=>"555-1234"}}
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 327
def permit(*filters) params = self.class.new filters.flatten.each do |filter| case filter when Symbol, String permitted_scalar_filter(params, filter) when Hash then hash_filter(params, filter) end end unpermitted_parameters!(params) if self.class.action_on_unpermitted_parameters params.permit! end
#permit!
Sets the permitted
attribute to true
. This can be used to pass mass assignment. Returns self
.
class Person < ActiveRecord::Base
end
params = ActionController::Parameters.new(name: 'Francesco')
params.permitted? # => false
Person.new(params) # => ActiveModel::ForbiddenAttributesError
params.permit!
params.permitted? # => true
Person.new(params) # => #<Person id: nil, name: "Francesco">
#require(key) Also known as: #required
Ensures that a parameter is present. If it's present, returns the parameter at the given key
, otherwise raises an ParameterMissing error.
ActionController::Parameters.new(person: { name: 'Francesco' }).require(:person)
# => {"name"=>"Francesco"}
ActionController::Parameters.new(person: nil).require(:person)
# => ActionController::ParameterMissing: param not found: person
ActionController::Parameters.new(person: {}).require(:person)
# => ActionController::ParameterMissing: param not found: person
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 246
def require(key) value = self[key] if value.present? || value == false value else raise ParameterMissing.new(key) end end
#required(key)
Alias for #require.
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 256
alias :required :require
#select!(&block)
Equivalent to Hash#keep_if
, but returns nil if no changes were made.
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 425
def select!(&block) convert_value_to_parameters(super) end
#slice(*keys)
Returns a new Parameters
instance that includes only the given keys
. If the given keys
don't exist, returns an empty hash.
params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
params.slice(:a, :b) # => {"a"=>1, "b"=>2}
params.slice(:d) # => {}
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 378
def slice(*keys) new_instance_with_inherited_permitted_status(super) end
#to_h
Returns a safe ::Hash representation of this parameter with all unpermitted keys removed.
params = ActionController::Parameters.new({
name: 'Senjougahara Hitagi',
oddity: 'Heavy stone crab'
})
params.to_h # => {}
safe_params = params.permit(:name)
safe_params.to_h # => {"name"=>"Senjougahara Hitagi"}
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 164
def to_h if permitted? to_hash else slice(*self.class.always_permitted_parameters).permit!.to_h end end
#to_unsafe_h Also known as: #to_unsafe_hash
Returns an unsafe, unfiltered ::Hash representation of this parameter.
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 173
def to_unsafe_h to_hash end
#to_unsafe_hash
Alias for #to_unsafe_h.
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 176
alias_method :to_unsafe_hash, :to_unsafe_h
#transform_values
Returns a new Parameters
with the results of running block
once for every value. The keys are unchanged.
params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
params.transform_values { |x| x * 2 }
# => {"a"=>2, "b"=>4, "c"=>6}
# File 'actionpack/lib/action_controller/metal/strong_parameters.rb', line 397
def transform_values if block_given? new_instance_with_inherited_permitted_status(super) else super end end