Allows you to choose which attributes should be permitted 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 # => #"Francesco", "age"=>22> permitted: true> permitted.permitted? # => true Person.first.update!(permitted) # => #
It provides two options that controls the top-level behavior of new instances:
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) # => # permitted: true> 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.
You can fetch values of ActionController::Parameters using either :key or "key" .
params = ActionController::Parameters.new(key: "value") params[:key] # => "value" params["key"] # => "value"
This is a 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 one in the permit doc as well.
[R] | parameters |
[W] | permitted |
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 253 def allow_deprecated_parameters_hash_equality ActionController.deprecator.warn .squish `Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality` is deprecated and will be removed in Rails 8.0. WARNING end
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 260 def allow_deprecated_parameters_hash_equality=(value) ActionController.deprecator.warn .squish `Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality` is deprecated and will be removed in Rails 8.0. WARNING end
Returns a new ActionController::Parameters instance. Also, sets the permitted attribute to the default value of ActionController::Parameters.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) # => #
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 288 def initialize(parameters = <>, logging_context = <>) parameters.each_key do |key| unless key.is_a?(String) || key.is_a?(Symbol) raise InvalidParameterKey, "all keys must be Strings or Symbols, got: #" end end @parameters = parameters.with_indifferent_access @logging_context = logging_context @permitted = self.class.permit_all_parameters end
Returns true if another Parameters object contains the same content and permitted flag.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 302 def ==(other) if other.respond_to?(:permitted?) permitted? == other.permitted? && parameters == other.parameters else super end end
Returns a parameter for the given key . If not found, returns nil .
params = ActionController::Parameters.new(person: < name: "Francesco" >) params[:person] # => #"Francesco"> permitted: false> params[:none] # => nil
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 670 def [](key) convert_hashes_to_parameters(key, @parameters[key]) end
Assigns a value to a given key . The given key may still get filtered out when permit is called.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 676 def []=(key, value) @parameters[key] = value end
Returns a hash that can be used as the JSON representation for the parameters.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 181
Returns a new ActionController::Parameters instance with nil values removed.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 847 def compact new_instance_with_inherited_permitted_status(@parameters.compact) end
Removes all nil values in place and returns self , or nil if no changes were made.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 853 def compact! self if @parameters.compact! end
Returns a new ActionController::Parameters instance without the blank values. Uses Object#blank? for determining if a value is blank.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 859 def compact_blank reject < |_k, v| v.blank? > end
Removes all blank values in place and returns self. Uses Object#blank? for determining if a value is blank.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 865 def compact_blank! reject! < |_k, v| v.blank? > end
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 436 def converted_arrays @converted_arrays ||= Set.new end
Returns a duplicate ActionController::Parameters instance with the same permitted parameters.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 965 def deep_dup self.class.new(@parameters.deep_dup, @logging_context).tap do |duplicate| duplicate.permitted = @permitted end end
Returns a new ActionController::Parameters instance with self and other_hash merged recursively.
Like with Hash#merge in the standard library, a block can be provided to merge values.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 155
Same as #deep_merge , but modifies self .
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 170
Returns a new ActionController::Parameters instance with the results of running block once for every key. This includes the keys from the root hash and from all nested hashes and arrays. The values are unchanged.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 797 def deep_transform_keys(&block) new_instance_with_inherited_permitted_status( _deep_transform_keys_in_object(@parameters, &block).to_unsafe_h ) end
Returns the same ActionController::Parameters instance with changed keys. This includes the keys from the root hash and from all nested hashes and arrays. The values are unchanged.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 806 def deep_transform_keys!(&block) @parameters = _deep_transform_keys_in_object(@parameters, &block).to_unsafe_h self end
Deletes a key-value pair from Parameters and returns the value. If key is not found, returns nil (or, with optional code block, yields key and returns the result). This method is similar to extract! , which returns the corresponding ActionController::Parameters object.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 815 def delete(key, &block) convert_value_to_parameters(@parameters.delete(key, &block)) end
Extracts the nested parameter from the given keys by calling dig at each step. Returns nil if any intermediate step is nil .
params = ActionController::Parameters.new(foo: < bar: < baz: 1 >>) params.dig(:foo, :bar, :baz) # => 1 params.dig(:foo, :zot, :xyz) # => nil params2 = ActionController::Parameters.new(foo: [10, 11, 12]) params2.dig(:foo, 1) # => 11
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 714 def dig(*keys) convert_hashes_to_parameters(keys.first, @parameters[keys.first]) @parameters.dig(*keys) end
Calls block once for each key in the parameters, passing the key. If no block is given, an enumerator is returned instead.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 189
Convert all hashes in values into parameters, then yield each pair in the same way as Hash#each_pair .
Also aliased as: each# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 403 def each_pair(&block) return to_enum(__callee__) unless block_given? @parameters.each_pair do |key, value| yield [key, convert_hashes_to_parameters(key, value)] end self end
Convert all hashes in values into parameters, then yield each value in the same way as Hash#each_value .
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 415 def each_value(&block) return to_enum(:each_value) unless block_given? @parameters.each_pair do |key, value| yield convert_hashes_to_parameters(key, value) end self end
Returns true if the parameters have no key/value pairs.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 198
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 310 def eql?(other) self.class == other.class && permitted? == other.permitted? && parameters.eql?(other.parameters) end
Returns a new ActionController::Parameters instance that filters out the given keys .
params = ActionController::Parameters.new(a: 1, b: 2, c: 3) params.except(:a, :b) # => #3> permitted: false> params.except(:d) # => #1, "b"=>2, "c"=>3> permitted: false>
Also aliased as: without
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 742 def except(*keys) new_instance_with_inherited_permitted_status(@parameters.except(*keys)) end
Returns true if the given key is not present in the parameters.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 206
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) # => #1, "b"=>2> permitted: false> params # => #3> permitted: false>
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 752 def extract!(*keys) new_instance_with_inherited_permitted_status(@parameters.extract!(*keys)) end
Returns parameter value for the given key separated by delimiter .
params = ActionController::Parameters.new(id: "1_123", tags: "ruby,rails") params.extract_value(:id) # => ["1", "123"] params.extract_value(:tags, delimiter: ",") # => ["ruby", "rails"] params.extract_value(:non_existent_key) # => nil
Note that if the given key ‘s value contains blank elements, then the returned array will include empty strings.
params = ActionController::Parameters.new(tags: "ruby,rails,,web") params.extract_value(:tags, delimiter: ",") # => ["ruby", "rails", "", "web"]
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 983 def extract_value(key, delimiter: "_") @parameters[key]&.split(delimiter, -1) end
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 ActionController::ParameterMissing error; if a second argument is given, then that is returned (converted to an instance of ActionController::Parameters if possible); if a block is given, then that will be run and its result returned.
params = ActionController::Parameters.new(person: < name: "Francesco" >) params.fetch(:person) # => #"Francesco"> permitted: false> params.fetch(:none) # => ActionController::ParameterMissing: param is missing or the value is empty: none params.fetch(:none, <>) # => # permitted: false> params.fetch(:none, "Francesco") # => "Francesco" params.fetch(:none) < "Francesco" ># => "Francesco"
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 693 def fetch(key, *args) convert_value_to_parameters( @parameters.fetch(key) < if block_given? yield else args.fetch(0) < raise ActionController::ParameterMissing.new(key, @parameters.keys) > end > ) end