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 приложении.