Cайт веб-разработчика, программиста Ruby on Rails ESV Corp. Екатеринбург, Москва, Санкт-Петербург, Первоуральск

Админка на Ruby on Rails

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, необходимо сделать следующее:

  1. Добавить gem strong_parameters в ваш Gemfile
  2. Установить config.active_record.whitelist_attributes в false в application.rb
  3. Добавить include ActiveModel::ForbiddenAttributesProtection в ваши модели
  4. Переписать в контроллере фильтрацию параметров, например: params.require(:person).permit(:name, :age)

После перехода на Rails 4 достаточно будет отменить 3 первых шага.

Если вы все же хотите продолжить использовать attr_protected и attr_accessible, используйте gem protected_attributes в вашем Rails 4 приложении.