Как attr_accessible используется в Rails 4?


258

attr_accessible Кажется, больше не работает в моей модели.

Как можно разрешить массовое назначение в Rails 4?

Ответы:


447

Rails 4 теперь использует сильные параметры .

Защита атрибутов теперь выполняется в контроллере. Это пример:

class PeopleController < ApplicationController
  def create
    Person.create(person_params)
  end

  private

  def person_params
    params.require(:person).permit(:name, :age)
  end
end

Больше не нужно устанавливать attr_accessibleмодель.

Имея дело с accepts_nested_attributes_for

Чтобы использовать accepts_nested_attribute_forсо строгими параметрами, вам нужно указать, какие вложенные атрибуты должны быть в белом списке.

class Person
  has_many :pets
  accepts_nested_attributes_for :pets
end

class PeopleController < ApplicationController
  def create
    Person.create(person_params)
  end

  # ...

  private

  def person_params
    params.require(:person).permit(:name, :age, pets_attributes: [:name, :category])
  end
end

Ключевые слова говорят сами за себя, но на всякий случай вы можете найти больше информации о сильных параметрах в руководстве по Rails Action Controller .

Примечание : если вы все еще хотите использовать attr_accessible, вам нужно добавить protected_attributesв свой Gemfile. В противном случае вы столкнетесь с RuntimeError.


1
В документе не сказано, что attr_accessibleнужно удалить. Что будет, если мы сохраним это?
Лулалала

12
Вы получите ошибку, если не внесете некоторые изменения в свой Gemfile. RuntimeError in MicropostsController#index 'attr_accessible' is extracted out of Rails into a gem. Please use new recommended protection model for params(strong_parameters) or add 'protected_attributes' to your Gemfile to use old one.
Пользователь

6
Отличное объяснение. Тем не менее, на практике это отодвигает Rails от толстой модели, тонкого контроллера и т. Д., К тонким моделям и действительно раздутым контроллерам. Вы должны писать все эти вещи для каждого экземпляра, они не читаются хорошо, а вложение кажется болезненным. Старый attr_accessible / attr_accessor в модельной системе не был сломан и не нуждался в исправлении. В этом случае одно сообщение в блоге стало слишком популярным.
узо

1
Вам не нужно обрабатывать разрешенные параметры в ваших контроллерах. На самом деле это нарушение принципа единой ответственности. Взгляните на следующее сообщение в блоге edelpero.svbtle.com/strong-parameters-the-right-way
Пьер-Луи Готфруа

3
Так что трюки и часто меняющиеся API в сочетании с новой педантикой тратят много часов на разработку еще одного болезненного обновления Rails :-(
Brian Takita

22

Если вы предпочитаете attr_accessible, вы можете использовать его и в Rails 4. Вы должны установить его как gem:

gem 'protected_attributes'

после этого вы можете использовать attr_accessible в ваших моделях, как в Rails 3

Кроме того, и я думаю, что это лучший способ - использовать объекты форм для работы с массовым присваиванием и сохранения вложенных объектов, и вы также можете использовать gem protected_attributes таким образом

class NestedForm
   include  ActiveModel::MassAssignmentSecurity
   attr_accessible :name,
                   :telephone, as: :create_params
   def create_objects(params)
      SomeModel.new(sanitized_params(params, :create_params))
   end
end

1
Когда вы используете «сильные параметры», вы фильтруете параметры на уровне контроллера, и я не думаю, что это лучшая идея для всех приложений. Для меня лучший способ фильтрации параметров - использовать дополнительный слой. И мы можем использовать гем 'protected_attributes', чтобы написать этот слой
edikgat

4

Мы можем использовать

params.require(:person).permit(:name, :age)

где person это Model, вы можете передать этот код в методе person_params и использовать вместо params [: person] в методе create или методе else


2

Обновление для Rails 5:

gem 'protected_attributes' 

кажется, больше не работает. Но дайте:

драгоценный камень 'protected_attributes_continued'

попытка


1

1) Обновите Devise, чтобы он мог обрабатывать Rails 4.0, добавив эту строку в Gemfile вашего приложения:

gem 'devise', '3.0.0.rc' 

Затем выполните:

$ bundle

2) Добавить старый функционал attr_accessibleснова в рельсы 4.0

Попробуйте использовать attr_accessibleи не комментируйте это.

Добавьте эту строку в Gemfile вашего приложения:

gem 'protected_attributes'

Затем выполните:

$ bundle
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.