В 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
Разработан gemstrong_parameters, который позволяет вам подготовить приложение Rails 3 для использования Rails 4. Для подготовки вашего Rails 3 приложения с использованием strong parameters, необходимо сделать следующее:
В
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
стало в Rails 4
Для использования
accepts_nested_attribute_for
Обновление приложения Rails 3.x до Rails 4
Разработан
gem
strong_parameters
, который позволяет вам подготовить приложениеRails 3
для использованияRails 4
. Для подготовки вашегоRails 3
приложения с использованиемstrong parameters
, необходимо сделать следующее: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
приложении.