Spec-Zone.ru › Ruby on Rails 8.0

класс ActionController::Parameters

Родитель:
Объект

Контроллер действий Parameters

Позволяет выбрать, какие атрибуты следует разрешить для массового обновления, тем самым предотвращая случайное раскрытие нежелательных данных.

Предоставляет методы для фильтрации и требования параметров:

  • expect для безопасного разрешения и требования параметров в одном шаге.

  • permit для фильтрации параметров для массового назначения.

  • require для требования параметра или вывода ошибки.

Примеры:

params = ActionController::Parameters.new({
  person: {
    name: "Francesco",
    age:  22,
    role: "admin"
  }
})

permitted = params.expect(person: [:name, :age])
permitted # => #<ActionController::Parameters {"name"=>"Francesco", "age"=>22} permitted: true>

Person.first.update!(permitted)
# => #<Person id: 1, name: "Francesco", age: 22, role: "user">

Parameters предоставляет два варианта, которые управляют поведением новых экземпляров на верхнем уровне:

  • permit_all_parameters - Если это true, все параметры будут разрешены по умолчанию. Значение по умолчанию - false.

  • action_on_unpermitted_parameters - Управляет поведением при обнаружении параметров, которые явно не разрешены. Значение по умолчанию - :log в тестовых и отладочных средах, false в противном случае. Значения могут быть:

    • false для отсутствия действий.

    • :log для отправки события ActiveSupport::Notifications.instrument на тему unpermitted_parameters.action_controller и регистрации на уровне отладки.

    • :raise для вывода исключения ActionController::UnpermittedParameters.

Примеры:

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 {} 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

Обратите внимание, что эти параметры не являются потокобезопасными. В многопоточной среде их следует задавать только один раз во время запуска и никогда не изменять во время выполнения.

Вы можете получить значения ActionController::Parameters с помощью :key или "key".

params = ActionController::Parameters.new(key: "value")
params[:key]  # => "value"
params["key"] # => "value"

Константы

PERMITTED_SCALAR_TYPES

— Фильтрация ———————————————————-

Это список разрешенных скалярных типов, который включает типы, поддерживаемые в XML и JSON запросах.

Этот список используется, в частности, для фильтрации обычных запросов, String является первым элементом для быстрого обхода распространённого случая.

Если вы измените этот набор, обновите соответствующий набор в документации к методу permit.

Атрибуты

parameters[R]
permitted[W]

Публичные методы класса

new(parameters = {}, logging_context = {}) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 287
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: #{key.class}"
    end
  end

  @parameters = parameters.with_indifferent_access
  @logging_context = logging_context
  @permitted = self.class.permit_all_parameters
end

Возвращает новый экземпляр ActionController::Parameters. Также устанавливает атрибут permitted в значение по умолчанию 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) # => #<Person id: nil, name: "Francesco">

Публичные методы экземпляра

==(other) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 301
def ==(other)
  if other.respond_to?(:permitted?)
    permitted? == other.permitted? && parameters == other.parameters
  else
    super
  end
end

Возвращает true, если другой объект Parameters содержит тот же контент и разрешенный флаг.

Вызывает метод суперкласса
[](key) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 797
def [](key)
  convert_hashes_to_parameters(key, @parameters[key])
end

Возвращает параметр для заданного key. Если не найден, возвращает nil.

params = ActionController::Parameters.new(person: { name: "Francesco" })
params[:person] # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
params[:none]   # => nil
[]=(key, value) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 803
def []=(key, value)
  @parameters[key] = value
end

Присваивает значение заданному key. Заданный ключ может быть отфильтрован при вызове permit.

as_json(options=nil) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 194
    

Возвращает хэш, который может быть использован в качестве JSON-представления для параметров.

compact() Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 974
def compact
  new_instance_with_inherited_permitted_status(@parameters.compact)
end

Возвращает новый экземпляр ActionController::Parameters с удаленными значениями nil.

compact!() Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 980
def compact!
  self if @parameters.compact!
end

Удаляет все значения nil на месте и возвращает self, или nil, если изменений не было.

compact_blank() Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 986
def compact_blank
  reject { |_k, v| v.blank? }
end

Возвращает новый экземпляр ActionController::Parameters без пустых значений. Использует Object#blank? для определения того, является ли значение пустым.

compact_blank!() Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 992
def compact_blank!
  reject! { |_k, v| v.blank? }
end

Удаляет все пустые значения на месте и возвращает self. Использует Object#blank? для определения того, является ли значение пустым.

converted_arrays() Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 435
def converted_arrays
  @converted_arrays ||= Set.new
end

Атрибут, отслеживающий преобразованные массивы, если таковые имеются, чтобы избежать двойного цикла в распространенном случае permit + массовое присваивание. Определено в методе, чтобы создать его только при необходимости.

Testing членство все еще использует цикл, но он будет быстрее, чем наш собственный цикл, который преобразует значения. Кроме того, мы не будем создавать новый объект массива для каждого извлечения.

deep_dup() Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1092
def deep_dup
  self.class.new(@parameters.deep_dup, @logging_context).tap do |duplicate|
    duplicate.permitted = @permitted
  end
end

Возвращает дублирующий экземпляр ActionController::Parameters с теми же разрешенными параметрами.

deep_merge(other_hash, &block) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 168
    

Возвращает новый экземпляр ActionController::Parameters со значениями self и other_hash рекурсивно объединенными.

Как и с Hash#merge в стандартной библиотеке, для объединения значений может быть предоставлен блок.

deep_merge!(other_hash, &block) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 183
    

То же, что и #deep_merge, но изменяет self.

deep_transform_keys(&block) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 924
def deep_transform_keys(&block)
  new_instance_with_inherited_permitted_status(
    _deep_transform_keys_in_object(@parameters, &block).to_unsafe_h
  )
end

Возвращает новый экземпляр ActionController::Parameters с результатами выполнения block один раз для каждого ключа. Это включает ключи из корневого хэша и из всех вложенных хэшей и массивов. Значения остаются неизменными.

deep_transform_keys!(&block) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 933
def deep_transform_keys!(&block)
  @parameters = _deep_transform_keys_in_object(@parameters, &block).to_unsafe_h
  self
end

Возвращает тот же экземпляр ActionController::Parameters с измененными ключами. Это включает ключи из корневого хэша и из всех вложенных хэшей и массивов. Значения остаются неизменными.

delete(key, &block) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 942
def delete(key, &block)
  convert_value_to_parameters(@parameters.delete(key, &block))
end

Удаляет пару ключ-значение из Parameters и возвращает значение. Если key не найден, возвращает nil (или, с необязательным блоком кода, передает key и возвращает результат). Этот метод аналогичен extract!, который возвращает соответствующий объект ActionController::Parameters.

delete_if(&block)
Псевдоним для: reject!
dig(*keys) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 841
def dig(*keys)
  convert_hashes_to_parameters(keys.first, @parameters[keys.first])
  @parameters.dig(*keys)
end

Извлекает вложенный параметр из заданного keys путем вызова dig на каждом шаге. Возвращает nil, если какой-либо промежуточный шаг является 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
each(&block)
Псевдоним для: each_pair
each_key(&block) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 202
    

Вызывает блок один раз для каждого ключа в параметрах, передавая ключ. Если блок не задан, вместо этого возвращается перечислитель.

each_pair() { |key, convert_hashes_to_parameters(key, value)| ... } Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 402
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

Преобразует все хэши в значения в параметры, затем передает каждую пару так же, как Hash#each_pair.

Также имеет псевдоним: each
each_value() { |convert_hashes_to_parameters(key, value)| ... } Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 414
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

Преобразует все хэши в значения в параметры, затем передает каждое значение так же, как Hash#each_value.

empty?() Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 211
    

Возвращает true, если параметры не имеют пар ключ/значение.

eql?(other) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 309
def eql?(other)
  self.class == other.class &&
    permitted? == other.permitted? &&
    parameters.eql?(other.parameters)
end
except(*keys) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 869
def except(*keys)
  new_instance_with_inherited_permitted_status(@parameters.except(*keys))
end

Возвращает новый экземпляр ActionController::Parameters, который фильтрует заданные keys.

params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
params.except(:a, :b) # => #<ActionController::Parameters {"c"=>3} permitted: false>
params.except(:d)     # => #<ActionController::Parameters {"a"=>1, "b"=>2, "c"=>3} permitted: false>
Также является псевдонимом для: without
exclude?(key) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 219
    

Возвращает true, если заданный ключ отсутствует в параметрах.

expect(*filters) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 772
def expect(*filters)
  params = permit_filters(filters)
  keys = filters.flatten.flat_map { |f| f.is_a?(Hash) ? f.keys : f }
  values = params.require(keys)
  values.size == 1 ? values.first : values
end

expect является предпочтительным способом для требования и разрешения параметров. Он безопаснее, чем предыдущая рекомендация вызывать permit и require последовательно, что может привести к ошибкам 500, вызванным пользователем.

expect более строг в отношении типов, чтобы избежать ряда потенциальных проблем, которые могут возникнуть с шаблоном .require.permit.

Например:

params = ActionController::Parameters.new(comment: { text: "hello" })
params.expect(comment: [:text])
# => #<ActionController::Parameters { text: "hello" } permitted: true>

params = ActionController::Parameters.new(comment: [{ text: "hello" }, { text: "world" }])
params.expect(comment: [:text])
# => ActionController::ParameterMissing: param is missing or the value is empty or invalid: comment

Для того, чтобы разрешить массив параметров, массив должен быть определен явно. Используйте двойные квадратные скобки, массив внутри массива, чтобы объявить, что ожидается массив параметров.

params = ActionController::Parameters.new(comments: [{ text: "hello" }, { text: "world" }])
params.expect(comments: [[:text]])
# => [#<ActionController::Parameters { "text" => "hello" } permitted: true>,
#     #<ActionController::Parameters { "text" => "world" } permitted: true>]

params = ActionController::Parameters.new(comments: { text: "hello" })
params.expect(comments: [[:text]])
# => ActionController::ParameterMissing: param is missing or the value is empty or invalid: comments

expect предназначен для защиты от подделки массивов.

params = ActionController::Parameters.new(user: "hack")
# The previous way of requiring and permitting parameters will error
params.require(:user).permit(:name, pets: [:name]) # wrong
# => NoMethodError: undefined method `permit' for an instance of String

# similarly with nested parameters
params = ActionController::Parameters.new(user: { name: "Martin", pets: { name: "hack" } })
user_params = params.require(:user).permit(:name, pets: [:name]) # wrong
# user_params[:pets] is expected to be an array but is a hash

expect решает это, будучи более строгим в отношении типов.

params = ActionController::Parameters.new(user: "hack")
params.expect(user: [ :name, pets: [[:name]] ])
# => ActionController::ParameterMissing: param is missing or the value is empty or invalid: user

# with nested parameters
params = ActionController::Parameters.new(user: { name: "Martin", pets: { name: "hack" } })
user_params = params.expect(user: [:name, pets: [[:name]] ])
user_params[:pets] # => nil

Как показывают примеры, expect требует ключ :user, а также любые корневые ключи, подобные шаблону .require.permit. Если ожидается несколько корневых ключей, все они будут обязательными.

params = ActionController::Parameters.new(name: "Martin", pies: [{ type: "dessert", flavor: "pumpkin"}])
name, pies = params.expect(:name, pies: [[:type, :flavor]])
name # => "Martin"
pies # => [#<ActionController::Parameters {"type"=>"dessert", "flavor"=>"pumpkin"} permitted: true>]

При вызове с хэшем, содержащим несколько ключей, expect разрешит параметры и потребует ключи в том порядке, в котором они заданы в хэше, возвращая массив разрешенных параметров.

params = ActionController::Parameters.new(subject: { name: "Martin" }, object: { pie: "pumpkin" })
subject, object = params.expect(subject: [:name], object: [:pie])
subject # => #<ActionController::Parameters {"name"=>"Martin"} permitted: true>
object  # => #<ActionController::Parameters {"pie"=>"pumpkin"} permitted: true>

Помимо того, что он более строг в отношении параметров массива и хэша, expect использует permit внутренне, поэтому он будет вести себя аналогично.

params = ActionController::Parameters.new({
  person: {
    name: "Francesco",
    age:  22,
    pets: [{
      name: "Purplish",
      category: "dogs"
    }]
  }
})

permitted = params.expect(person: [ :name, { pets: [[:name]] } ])
permitted.permitted?           # => true
permitted[:name]               # => "Francesco"
permitted[:age]                # => nil
permitted[:pets][0][:name]     # => "Purplish"
permitted[:pets][0][:category] # => nil

Массив разрешенных скалярных значений может ожидаться со следующим:

params = ActionController::Parameters.new(tags: ["rails", "parameters"])
permitted = params.expect(tags: [])
permitted.permitted?      # => true
permitted.is_a?(Array)    # => true
permitted.size            # => 2
expect!(*filters) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 786
def expect!(*filters)
  expect(*filters)
rescue ParameterMissing => e
  raise ExpectedParameterMissing.new(e.param, e.keys)
end

То же, что и expect, но вызывает ActionController::ExpectedParameterMissing вместо ActionController::ParameterMissing. В отличие от expect, который будет отображать ответ 400, expect! вызовет исключение, которое не обрабатывается. Это предназначено для отладки недопустимых параметров для внутреннего API, где неправильно отформатированные параметры укажут на ошибку в клиентской библиотеке, которую следует исправить.

extract!(*keys) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 879
def extract!(*keys)
  new_instance_with_inherited_permitted_status(@parameters.extract!(*keys))
end

Удаляет и возвращает пары ключ/значение, соответствующие заданным ключам.

params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
params.extract!(:a, :b) # => #<ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
params                  # => #<ActionController::Parameters {"c"=>3} permitted: false>
extract_value(key, delimiter: "_") Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1110
def extract_value(key, delimiter: "_")
  @parameters[key]&.split(delimiter, -1)
end

Возвращает значение параметра для заданного key, разделенного 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

Обратите внимание, что если значение заданного key содержит пустые элементы, то возвращаемый массив будет включать пустые строки.

params = ActionController::Parameters.new(tags: "ruby,rails,,web")
params.extract_value(:tags, delimiter: ",") # => ["ruby", "rails", "", "web"]
fetch(key, *args) { || ... } Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 820
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

Возвращает параметр для заданного key. Если key не может быть найден, есть несколько вариантов: без других аргументов он вызовет ошибку ActionController::ParameterMissing; если задан второй аргумент, то он возвращается (преобразуется в экземпляр ActionController::Parameters, если это возможно); если задан блок, то он будет выполнен и его результат будет возвращен.

params = ActionController::Parameters.new(person: { name: "Francesco" })
params.fetch(:person)               # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
params.fetch(:none)                 # => ActionController::ParameterMissing: param is missing or the value is empty or invalid: none
params.fetch(:none, {})             # => #<ActionController::Parameters {} permitted: false>
params.fetch(:none, "Francesco")    # => "Francesco"
params.fetch(:none) { "Francesco" } # => "Francesco"
has_key?
Псевдоним для: include?
has_value?(value) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 997
def has_value?(value)
  each_value.include?(convert_value_to_parameters(value))
end

Возвращает true, если заданное значение присутствует для некоторого ключа в параметрах.

Также является псевдонимом для: value?
hash() Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 315
def hash
  [self.class, @parameters, @permitted].hash
end
include?(key) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 227
    

Возвращает true, если заданный ключ присутствует в параметрах.

Также является псевдонимом для: has_key?, key?, member?
inspect() Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1055
def inspect
  "#<#{self.class} #{@parameters} permitted: #{@permitted}>"
end
keep_if(&block)
Псевдоним для: select!
key?
Псевдоним для: include?
keys() Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 235
    

Возвращает новый массив ключей параметров.

member?
Псевдоним для: include?
merge(other_hash) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1011
def merge(other_hash)
  new_instance_with_inherited_permitted_status(
    @parameters.merge(other_hash.to_h)
  )
end

Возвращает новый экземпляр ActionController::Parameters со всеми ключами из other_hash, объединенными в текущий хэш.

merge!(other_hash) Show source
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1022
def merge!(other_hash, &block)
  @parameters.merge!(other_hash.to_h, &block)
  self
end

Возвращает текущий экземпляр ActionController::Parameters с other_hash, объединенными в текущий хэш.

permit(*filters) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 668
def permit(*filters)
  permit_filters(filters, on_unpermitted: self.class.action_on_unpermitted_parameters, explicit_arrays: false)
end

Возвращает новый экземпляр ActionController::Parameters, содержащий только указанные filters, и устанавливает атрибут permitted объекта в значение true. Это полезно для ограничения атрибутов, которые должны быть разрешены для массового обновления.

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

Только разрешенные скалярные значения проходят фильтр. Например, при

params.permit(:name)

:name проходит, если это ключ params, соответствующее значение которого имеет тип String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, DateTime, StringIO, IO, ActionDispatch::Http::UploadedFile или Rack::Test::UploadedFile. В противном случае ключ :name отфильтровывается.

Вы можете указать, что параметр должен быть массивом разрешенных скалярных значений, сопоставив его с пустым массивом:

params = ActionController::Parameters.new(tags: ["rails", "parameters"])
params.permit(tags: [])

Иногда невозможно или неудобно указывать допустимые ключи параметра типа хэш или его внутреннюю структуру. Просто сопоставьте его с пустым хэшем:

params.permit(preferences: {})

Будьте осторожны, потому что это открывает возможность произвольного ввода. В этом случае permit гарантирует, что значения в возвращаемой структуре являются разрешенными скалярными значениями, и отфильтровывает все остальное.

Вы также можете использовать permit для вложенных параметров:

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

Это предоставляет дополнительное преимущество в отклонении измененных пользователем вводов, которые отправляют строку вместо ожидаемого хэша.

Если за этим следует require, вы можете одновременно фильтровать и требовать параметров, следуя стандартному шаблону формы Rails. Метод expect был создан специально для этого случая и является рекомендуемым способом требования и разрешения параметров.

 permitted = params.expect(person: [:name, :age])

При использовании permit и require по отдельности, обратите пристальное внимание на порядок вызовов методов.

 params = ActionController::Parameters.new(person: { name: "Martin", age: 40, role: "admin" })
 permitted = params.permit(person: [:name, :age]).require(:person) # correct

Если require используется первым, пользователи вашего приложения могут вызвать NoMethodError, когда пользователь, например, отправит строку для :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

Обратите внимание, что если вы используете permit в ключе, указывающем на хэш, он не разрешит весь хэш. Вам также нужно указать, какие атрибуты внутри хэша должны быть разрешены.

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>

Если ваши параметры указывают на несколько параметров, индексированных по номеру, вы можете разрешить каждый набор параметров под числовым ключом быть одинаковыми, используя тот же синтаксис, что и для разрешения одного элемента.

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"}}}

Если вы хотите указать, какие ключи вы хотите получить из каждого числового ключа, вы можете указать каждый из них индивидуально

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"}}}
permit!() Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 461
def permit!
  each_pair do |key, value|
    Array.wrap(value).flatten.each do |v|
      v.permit! if v.respond_to? :permit!
    end
  end

  @permitted = true
  self
end

Устанавливает атрибут permitted в значение true. Это можно использовать для пропуска массового назначения. Возвращает 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">
permitted?() Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 445
def permitted?
  @permitted
end

Возвращает true , если параметр разрешен, false в противном случае.

params = ActionController::Parameters.new
params.permitted? # => false
params.permit!
params.permitted? # => true
reject(&block) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 961
def reject(&block)
  new_instance_with_inherited_permitted_status(@parameters.reject(&block))
end

Возвращает новый экземпляр ActionController::Parameters с удаленными элементами, для которых блок возвращает true.

reject!(&block) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 966
def reject!(&block)
  @parameters.reject!(&block)
  self
end

Удаляет элементы, для которых блок возвращает true, и возвращает self.

Также алиас для: delete_if
require(key) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 519
def require(key)
  return key.map { |k| require(k) } if key.is_a?(Array)
  value = self[key]
  if value.present? || value == false
    value
  else
    raise ParameterMissing.new(key, @parameters.keys)
  end
end

Этот метод принимает как одиночный ключ, так и массив ключей.

При передаче одного ключа, если он существует и его связанное значение присутствует или является синглтоном false, возвращает это значение:

ActionController::Parameters.new(person: { name: "Francesco" }).require(:person)
# => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>

В противном случае вызывает ActionController::ParameterMissing:

ActionController::Parameters.new.require(:person)
# ActionController::ParameterMissing: param is missing or the value is empty or invalid: person

ActionController::Parameters.new(person: nil).require(:person)
# ActionController::ParameterMissing: param is missing or the value is empty or invalid: person

ActionController::Parameters.new(person: "\t").require(:person)
# ActionController::ParameterMissing: param is missing or the value is empty or invalid: person

ActionController::Parameters.new(person: {}).require(:person)
# ActionController::ParameterMissing: param is missing or the value is empty or invalid: person

При передаче массива ключей, метод пытается последовательно получить каждый из них. Если это успешно, возвращается массив соответствующих возвращаемых значений:

params = ActionController::Parameters.new(user: { ... }, profile: { ... })
user_params, profile_params = params.require([:user, :profile])

В противном случае метод повторно вызывает первый пойманный исключение:

params = ActionController::Parameters.new(user: {}, profile: {})
user_params, profile_params = params.require([:user, :profile])
# ActionController::ParameterMissing: param is missing or the value is empty or invalid: user

Этот метод не рекомендуется для получения конечных значений, так как он не допускает значения. Например, это может вызвать проблемы:

# CAREFUL
params = ActionController::Parameters.new(person: { name: "Finn" })
name = params.require(:person).require(:name) # CAREFUL

Рекомендуется использовать expect вместо него:

def person_params
  params.expect(person: :name).require(:name)
end
Также алиас для: required
required(key)
Псевдоним для: require
reverse_merge(other_hash) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1033
def reverse_merge(other_hash)
  new_instance_with_inherited_permitted_status(
    other_hash.to_h.merge(@parameters)
  )
end

Возвращает новый экземпляр ActionController::Parameters с объединением всех ключей текущего хэша в other_hash.

Также алиас для: with_defaults
reverse_merge!(other_hash) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1042
def reverse_merge!(other_hash)
  @parameters.merge!(other_hash.to_h) { |key, left, right| left }
  self
end

Возвращает текущий экземпляр ActionController::Parameters с объединением текущего хэша в other_hash.

Также алиас для: with_defaults!
select(&block) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 948
def select(&block)
  new_instance_with_inherited_permitted_status(@parameters.select(&block))
end

Возвращает новый экземпляр ActionController::Parameters только с элементами, для которых блок возвращает true.

select!(&block) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 953
def select!(&block)
  @parameters.select!(&block)
  self
end

Эквивалентно Hash#keep_if, но возвращает nil , если изменений не было.

Также алиас для: keep_if
slice(*keys) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 852
def slice(*keys)
  new_instance_with_inherited_permitted_status(@parameters.slice(*keys))
end

Возвращает новый экземпляр ActionController::Parameters , содержащий только указанные keys. Если указанные keys не существуют, возвращает пустой хэш.

params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
params.slice(:a, :b) # => #<ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
params.slice(:d)     # => #<ActionController::Parameters {} permitted: false>
slice!(*keys) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 858
def slice!(*keys)
  @parameters.slice!(*keys)
  self
end

Возвращает текущий экземпляр ActionController::Parameters , содержащий только указанные keys.

to_h(&block) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 331
def to_h(&block)
  if permitted?
    convert_parameters_to_hashes(@parameters, :to_h, &block)
  else
    raise UnfilteredParameters
  end
end

Возвращает безопасное представление ActiveSupport::HashWithIndifferentAccess параметров со всеми неразрешенными ключами, удаленными.

params = ActionController::Parameters.new({
  name: "Senjougahara Hitagi",
  oddity: "Heavy stone crab"
})
params.to_h
# => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash

safe_params = params.permit(:name)
safe_params.to_h # => {"name"=>"Senjougahara Hitagi"}
to_hash() Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 351
def to_hash
  to_h.to_hash
end

Возвращает безопасное Hash представление параметров со всеми запрещенными ключами, удаленными.

params = ActionController::Parameters.new({
  name: "Senjougahara Hitagi",
  oddity: "Heavy stone crab"
})
params.to_hash
# => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash

safe_params = params.permit(:name)
safe_params.to_hash # => {"name"=>"Senjougahara Hitagi"}
to_param(*args)
Псевдоним для: to_query
to_query(*args) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 381
def to_query(*args)
  to_h.to_query(*args)
end

Возвращает строковое представление получателя, подходящее для использования в качестве строки запроса URL:

params = ActionController::Parameters.new({
  name: "David",
  nationality: "Danish"
})
params.to_query
# => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash

safe_params = params.permit(:name, :nationality)
safe_params.to_query
# => "name=David&nationality=Danish"

Можно передать необязательное имя пространства для включения имён ключей:

params = ActionController::Parameters.new({
  name: "David",
  nationality: "Danish"
})
safe_params = params.permit(:name, :nationality)
safe_params.to_query("user")
# => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"

Строки пар "key=value", составляющие строку запроса, сортируются лексикографически в порядке возрастания.

Также псевдоним для: to_param
to_s() Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 250
delegate :keys, :empty?, :exclude?, :include?,
  :as_json, :to_s, :each_key, to: :@parameters

Возвращает содержимое параметров в виде строки.

to_unsafe_h() Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 395
def to_unsafe_h
  convert_parameters_to_hashes(@parameters, :to_unsafe_h)
end

Возвращает небезопасное, неотфильтрованное ActiveSupport::HashWithIndifferentAccess представление параметров.

params = ActionController::Parameters.new({
  name: "Senjougahara Hitagi",
  oddity: "Heavy stone crab"
})
params.to_unsafe_h
# => {"name"=>"Senjougahara Hitagi", "oddity" => "Heavy stone crab"}
Также псевдоним для: to_unsafe_hash
to_unsafe_hash()
Псевдоним для: to_unsafe_h
transform_keys(&block) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 906
def transform_keys(&block)
  return to_enum(:transform_keys) unless block_given?
  new_instance_with_inherited_permitted_status(
    @parameters.transform_keys(&block)
  )
end

Возвращает новый ActionController::Parameters экземпляр с результатами выполнения block для каждого ключа. Значения остаются неизменными.

transform_keys!(&block) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 915
def transform_keys!(&block)
  return to_enum(:transform_keys!) unless block_given?
  @parameters.transform_keys!(&block)
  self
end

Выполняет преобразование ключей и возвращает измененный ActionController::Parameters экземпляр.

transform_values() { |convert_value_to_parameters(v)| ... } Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 889
def transform_values
  return to_enum(:transform_values) unless block_given?
  new_instance_with_inherited_permitted_status(
    @parameters.transform_values { |v| yield convert_value_to_parameters(v) }
  )
end

Возвращает новый ActionController::Parameters экземпляр с результатами выполнения block для каждого значения. Ключи остаются неизменными.

params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
params.transform_values { |x| x * 2 }
# => #<ActionController::Parameters {"a"=>2, "b"=>4, "c"=>6} permitted: false>
transform_values!() { |convert_value_to_parameters(v)| ... } Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 898
def transform_values!
  return to_enum(:transform_values!) unless block_given?
  @parameters.transform_values! { |v| yield convert_value_to_parameters(v) }
  self
end

Выполняет преобразование значений и возвращает измененный ActionController::Parameters экземпляр.

value?(value)
Псевдоним для: has_value?
values() Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 424
def values
  to_enum(:each_value).to_a
end

Возвращает новый массив значений параметров.

values_at(*keys) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1005
def values_at(*keys)
  convert_value_to_parameters(@parameters.values_at(*keys))
end

Возвращает значения, которые были назначены указанным keys. Обратите внимание, что все объекты Hash будут преобразованы в ActionController::Parameters.

with_defaults(other_hash)
Псевдоним для: reverse_merge
with_defaults!(other_hash)
Псевдоним для: reverse_merge!
without(*keys)
Псевдоним для: except

Защищенные методы экземпляра

each_nested_attribute() { |v| ... } Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1123
def each_nested_attribute
  hash = self.class.new
  self.each { |k, v| hash[k] = yield v if Parameters.nested_attribute?(k, v) }
  hash
end
nested_attributes?() Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1119
def nested_attributes?
  @parameters.any? { |k, v| Parameters.nested_attribute?(k, v) }
end
permit_filters(filters, on_unpermitted: nil, explicit_arrays: true) Показать исходный код
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1130
def permit_filters(filters, on_unpermitted: nil, explicit_arrays: true)
  params = self.class.new

  filters.flatten.each do |filter|
    case filter
    when Symbol, String
      # Declaration [:name, "age"]
      permitted_scalar_filter(params, filter)
    when Hash
      # Declaration [{ person: ... }]
      hash_filter(params, filter, on_unpermitted:, explicit_arrays:)
    end
  end

  unpermitted_parameters!(params, on_unpermitted:)

  params.permit!
end

Фильтры self и, по желанию, проверка на запрещенные ключи

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API