Strong Parameters in Ruby on Rails 4
В Rails 3.x
все атрибуты модели (model attributes) защищены по умолчанию. Они становятся доступны для массового присвоения значений (mass assignment) только если указаны в списке attr_accessible
.
В Rails 4
был введен новый способ защиты модели при массовом присвоения. Вы можете фильтровать параметры, переданные для присвоения полям модели в контроллере вместо перечисления атрибутов модели, используя attr_accessible
.
Детали реализации
Хэш параметров params
в контроллере - экземляр класса ActionController::Parameters
. Когда этот хэш параметров используется для массового присвоения атрибутам модели, ActiveModel
будет проверять разрешенные для присвоения атрибуты, указанные в хэше. Разрешенные атрибуты false
по умолчанию. Вы можете установить их в true
используя permit!
или permits
.
ActionController::Parameters
имеет два полезных метода:
require(key)
: получает значение хеша по ключуkey
и вызывает исключениеActionController::ParameterMissing
если в хэше нет такого ключа.permit(keys)
: выбирает только указанные ключи (keys
) из хэша параметров и помечает их как разрешенные.
Пример
Пример того, как производится массовое присвоение name
и age
для модели Person.
как было в Rails 3.x
class PeopleController < ApplicationController ... def create @person = Person.create(params[:person]) ... end ... end
class Person < ActiveRecord::Base attr_accessible :name, :age # должны быть перечислены все атрибуты # доступные для массового присвоения end
стало в Rails 4
class PeopleController < ApplicationController ... def create @person = Person.create(person_params) ... end ... private def person_params params.require(:person).permit(:name, :age) end end
Для использования accepts_nested_attribute_for
class Person has_many :pets accepts_nested_attributes_for :pets end class PeopleController < ActionController::Base def create Person.create(person_params) end ... private def person_params # It's mandatory to specify the nested attributes that should be whitelisted. # If you use `permit` with just the key that points to the nested attributes hash, # it will return an empty hash. params.require(:person).permit(:name, :age, pets_attributes: [ :name, :category ]) end end
Обновление приложения Rails 3.x до Rails 4
Разработан gem
strong_parameters
, который позволяет вам подготовить приложение Rails 3
для использования Rails 4
. Для подготовки вашего Rails 3
приложения с использованием strong parameters
, необходимо сделать следующее:
- Добавить gem strong_parameters в ваш Gemfile
- Установить
config.active_record.whitelist_attributes
вfalse
вapplication.rb
- Добавить
include ActiveModel::ForbiddenAttributesProtection
в ваши модели - Переписать в контроллере фильтрацию параметров, например:
params.require(:person).permit(:name, :age)
После перехода на Rails 4
достаточно будет отменить 3 первых шага.
Если вы все же хотите продолжить использовать attr_protected
и attr_accessible
, используйте gem protected_attributes в вашем Rails 4
приложении.