modulos herencia clases ruby-on-rails activemodel

ruby on rails - herencia - ActiveModel:: MassAssignmentSecurity:: Error: No se pueden asignar en masa atributos protegidos



modulo ruby (6)

Si intento ejecutar el siguiente código:

hassle = rota.hassles.create(:sender => user1, :receiver => user2, :type => "sms")

Obtengo el siguiente error:

Failure/Error: hassle = rota.hassles.create(:sender => user1, :receiver => user2, :type => "sms") ActiveModel::MassAssignmentSecurity::Error: Can''t mass-assign protected attributes: type

No estoy seguro de lo que esto significa. He hecho que: type sea obligatorio, así que si lo elimino, aparece un error de SQL.


  1. Por favor intente: abra config/application.rb

  2. Localice la línea de config.active_record.whitelist_attributes = true

  3. Cambiar de verdadero a falso

Entonces estarás bien.

PD: recuerda reiniciar la consola de rieles.


¿Trabaja con Rails 3.2 mientras sigue un tutorial 3.1, como la 4ta edición de "Desarrollo web ágil con Rails" del Programador pragmático? Luego verifique http://guides.rubyonrails.org/3_2_release_notes.html .

Su problema es que desde Rails 3.1 a 3.2, la comprobación de la protección de asignación en masa para los modelos de Registro Activo está configurada en "estricta" por defecto. Comente las líneas apropiadas en estos archivos:

config/environments/development.rb config/environments/test.rb

... y eres bueno para seguir aprendiendo. Recuerde dejar esto vigente cuando codifique su primera aplicación de producción :)


Debería estar recibiendo otro error, como este: la columna ''tipo'' está reservada para almacenar la clase en caso de herencia. Debido a que la columna ''tipo'' no debe usarse en la base de datos de registros activos.


No uso whitelist_attributes ya que los casos de uso cuando quiero permitir la asignación masiva son para mi lógica interna y, por lo general, no directamente en el Controlador para las acciones de CRUD. Sugiero usar params fuertes en esos casos. Pero cuando desea habilitar la asignación masiva para un modelo específico, lo hace

class Foo < ActiveRecord::Base # disables mass-assigment attr_protected end

Esto básicamente establece attr_protected a una matriz vacía ([])


Un par de cosas:

La asignación de masa generalmente significa pasar atributos a la llamada que crea un objeto como parte de un hash de atributos . Es decir, pasa un grupo de atributos en un hash a la llamada que crea el nuevo objeto. Por ejemplo:

@user = User.create({:name => "My name", :user_type => "nice_user"})

Sin embargo, Rails incluye algunas reglas de seguridad básicas que significan que no todos los atributos pueden asignarse de esa manera por defecto . Tienes que especificar de antemano cuáles puedes. Lo haces así:

class User < ActiveRecord::Base attr_accessible :name, :user_type end

Si no especifica que un atributo es attr_accessible , y lo pasa para crear el objeto, obtiene el error que publicó.

Aquí hay más detalles:

http://api.rubyonrails.org/v3.2.9/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html

La alternativa es establecer algunos de los atributos cuando crea el registro por primera vez, y establecer otros después, como:

# In this example `user_type` is not attr_accessible so it needs to be set specifically @user = User.create({:name => "My name"}) @user.user_type = "nice_user" @user.save

Además, si tiene problemas con el uso del type nombre de columna porque los rieles se confunden y cree que desea usar la herencia de una sola tabla (STI), verifique la respuesta a esta pregunta para ver cómo http://guides.rubyonrails.org/


Here hay algo de información sobre qué es la asignación masiva en Rails y por qué está establecida la protección. Es bastante fácil moverse cuando realmente desea asignar un atributo protegido, pero toma un par de líneas adicionales.

hassle = rota.hassles.build(:sender => user1, :receiver => user2) hassle.type = ''sms'' hassle.save