Como o attr_accessible é usado no Rails 4?

258

attr_accessible parece não funcionar mais dentro do meu modelo.

Qual é a maneira de permitir a atribuição em massa no Rails 4?

user2532974
fonte

Respostas:

447

O Rails 4 agora usa parâmetros fortes .

A proteção de atributos agora é feita no controlador. Isto é um exemplo:

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

  private

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

Não é mais necessário definir attr_accessibleo modelo.

Lidando com accepts_nested_attributes_for

Para usar accepts_nested_attribute_forcom parâmetros fortes, você precisará especificar quais atributos aninhados devem ser incluídos na lista de permissões.

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

As palavras-chave são auto-explicativas, mas por precaução, você pode encontrar mais informações sobre parâmetros fortes no guia do Rails Action Controller .

Nota : Se você ainda deseja usar attr_accessible, precisará adicionar protected_attributesao seu Gemfile. Caso contrário, você será confrontado com um RuntimeError.

Pierre-Louis Gottfrois
fonte
1
O documento não dizia que attr_accessibleprecisava ser removido. O que acontecerá se mantivermos?
Lulalala 11/11/2013
12
Você receberá um erro se não fizer alguns ajustes no seu 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.
usuário
6
Ótima explicação. Parece que, na prática, isso afasta o Rails do modelo gordo, do controlador fino, etc, e para os modelos finos, e para os controladores realmente inchados. Você tem que escrever todas essas coisas para todas as instâncias, não lê bem, e aninhar parece ser uma dor. O antigo attr_accessible / attr_accessor no sistema de modelo não estava quebrado e não precisou ser corrigido. Uma postagem de blog ficou muito popular nesse caso.
RCD
1
Você não precisa manipular parâmetros permitidos em seus controladores. De fato, é uma violação do princípio da responsabilidade única. Dê uma olhada na seguinte publicação no blog edelpero.svbtle.com/strong-parameters-the-right-way
Pierre-Louis Gottfrois
3
Então gimmiky & mudam frequentemente apis, juntamente com pedantics recém desperdiçar muitas horas de desenvolvedor em outro dolorosas Rails atualizar :-(
Brian Takita
22

Se você preferir attr_accessible, também poderá usá-lo no Rails 4. Você deve instalá-lo como gem:

gem 'protected_attributes'

depois disso, você poderia usar attr_accessible em seus modelos, como no Rails 3

Além disso, e acho que é a melhor maneira de usar objetos de formulário para lidar com atribuição em massa e salvar objetos aninhados, e você também pode usar a gema protected_attributes dessa maneira

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
edikgat
fonte
1
Quando você usa 'parâmetros fortes', você filtra os parâmetros na camada do controlador, e eu não acho que essa seja a melhor ideia para todas as aplicações. Para mim, a melhor maneira de filtrar parâmetros é usar camada adicional. E podemos usar gem 'protected_attributes' para escrever esta camada
edikgat
4

Podemos usar

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

onde person é Model, você pode passar esse código em um método person_params e usá-lo no lugar de params [: person] no método create ou no método

Hardik Hardiya
fonte
2

Uma atualização para o Rails 5:

gem 'protected_attributes' 

parece não funcionar mais. Mas dê:

gem 'protected_attributes_continued'

uma tentativa.

miklki14567
fonte
1

1) Atualize o Devise para que ele possa lidar com o Rails 4.0 adicionando esta linha ao Gemfile do seu aplicativo:

gem 'devise', '3.0.0.rc' 

Em seguida, execute:

$ bundle

2) Adicione a funcionalidade antiga de attr_accessiblenovo ao Rails 4.0

Tente usar attr_accessiblee não comente isso.

Adicione esta linha ao Gemfile do seu aplicativo:

gem 'protected_attributes'

Em seguida, execute:

$ bundle
Sid
fonte