class ActionController::Parameters
Параметры Action Controller
Позволяет выбрать атрибуты, которые следует включить в белый список для массового обновления, предотвращая случайное раскрытие нежелательных данных. Для этой цели предоставляются два метода: require и permit. Первый используется для обозначения параметров как обязательных. Последний используется для разрешения параметра и ограничения атрибутов, разрешённых для массового обновления.
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">
Предоставляет две опции, которые контролируют поведение новых экземпляров на верхнем уровне:
-
permit_all_parameters- Если этоtrue, все параметры будут разрешены по умолчанию. По умолчанию этоfalse. -
action_on_unpermitted_parameters- Позволяет контролировать поведение при обнаружении параметров, которые явно не разрешены. Значения могут быть:logдля записи сообщения в логгер или:raiseдля повышения исключения ActionController::UnpermittedParameters. Значение по умолчанию —:logв тестовых и разработочных средах,falseв остальных.
Примеры:
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
Обратите внимание, что эти параметры *не являются потокобезопасными*. В многопоточной среде они должны устанавливаться только один раз во время запуска и никогда не изменяться во время выполнения.
ActionController::Parameters наследуется от ActiveSupport::HashWithIndifferentAccess, это означает, что вы можете получить значения, используя либо :key или "key".
params = ActionController::Parameters.new(key: 'value') params[:key] # => "value" params["key"] # => "value"
Константы
- EMPTY_ARRAY
- PERMITTED_SCALAR_TYPES
-
Это белый список разрешенных скалярных типов, включающий поддерживаемые в XML и JSON запросах.
Этот список используется, в частности, для фильтрации обычных запросов, String стоит первым элементом для быстрого сокращения общего случая.
Если вы изменяете этот список, пожалуйста, обновите API
permitвыше.
Публичные методы класса
# 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(" `ActionController::Parameters::NEVER_UNPERMITTED_PARAMS` has been deprecated.
Use `ActionController::Parameters.always_permitted_parameters` instead.
".squish)
always_permitted_parameters
end # File actionpack/lib/action_controller/metal/strong_parameters.rb, line 148 def initialize(attributes = nil) super(attributes) @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">
Методы публичного экземпляра
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 350 def [](key) convert_hashes_to_parameters(key, super) end
Возвращает параметр для заданного key. Если не найден, возвращает 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 197 def converted_arrays @converted_arrays ||= Set.new end
Атрибут, отслеживающий преобразованные массивы (если таковые имеются), чтобы избежать двойного циклирования в распространённом случае с разрешениями + массовым назначением. Определён в методе для инициализации только при необходимости.
Тестирование членства всё ещё выполняет циклирование, но это будет быстрее, чем наш собственный цикл, преобразующий значения. Кроме того, мы не будем создавать новый объект массива при каждом извлечении.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 420 def delete(key, &block) convert_hashes_to_parameters(key, super, false) end
Удаляет и возвращает пару «ключ-значение» из Parameters, у которого ключ равен key. Если ключ не найден, возвращает значение по умолчанию. Если задан необязательный блок кода, и ключ не найден, передаёт ключ и возвращает результат выполнения блока.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 437
def dup
super.tap do |duplicate|
duplicate.permitted = @permitted
end
end Возвращает точную копию экземпляра ActionController::Parameters. permitted состояние сохраняется в дублированном объекте.
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 180
def each_pair(&block)
super do |key, value|
convert_hashes_to_parameters(key, value)
end
super
end Преобразует все хэши в значения в параметры, затем передает каждую пару таким же образом, как и Hash#each_pair
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 387 def extract!(*keys) new_instance_with_inherited_permitted_status(super) end
Удаляет и возвращает пары «ключ-значение», соответствующие заданным ключам.
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 365 def fetch(key, *args) convert_hashes_to_parameters(key, super, false) rescue KeyError raise ActionController::ParameterMissing.new(key) end
Возвращает параметр для заданного key. Если key не найден, есть несколько вариантов: без дополнительных аргументов он вызывает ошибку ActionController::ParameterMissing; если заданы дополнительные аргументы, они возвращаются; если задан блок, выполняется блок, и возвращается его результат.
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 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 Возвращает новый экземпляр ActionController::Parameters, включающий только заданные filters, и устанавливает атрибут permitted объекта в true. Это полезно для ограничения атрибутов, которые должны разрешаться для массового обновления.
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
Только разрешённые скаляры проходят фильтр. Например, при
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: [])
Вы также можете использовать 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
Обратите внимание, что если вы используете permit в ключе, который указывает на хэш, он не позволит использовать весь хэш. Вам также необходимо указать, какие атрибуты внутри хэша должны быть включены в белый список.
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 223
def permit!
each_pair do |key, value|
Array.wrap(value).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">
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 207 def permitted? @permitted end
Возвращает true, если параметр разрешён, false в противном случае.
params = ActionController::Parameters.new params.permitted? # => false params.permit! params.permitted? # => true
# 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 Обеспечивает наличие параметра. Если он присутствует, возвращает параметр по заданному key, иначе вызывает ошибку ActionController::ParameterMissing.
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 425 def select!(&block) convert_value_to_parameters(super) end
Эквивалентно Hash#keep_if, но возвращает nil, если изменений не было.
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 378 def slice(*keys) new_instance_with_inherited_permitted_status(super) end
Возвращает новый экземпляр ActionController::Parameters, включающий только заданные keys. Если заданные keys не существуют, возвращает пустой хэш.
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 164
def to_h
if permitted?
to_hash
else
slice(*self.class.always_permitted_parameters).permit!.to_h
end
end Возвращает безопасное представление Hash этого параметра со всеми неразрешёнными ключами, удалёнными.
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 173 def to_unsafe_h to_hash end
Возвращает небезопасное, нефильтрованное представление Hash этого параметра.
# 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 Возвращает новый ActionController::Parameters с результатами выполнения block один раз для каждого значения. Ключи остаются неизменными.
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 444 def permitted=(new_permitted) @permitted = new_permitted end
© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.