2012-05-13 14 views
24

Si trato de ejecutar el siguiente código:ActiveModel :: :: MassAssignmentSecurity Error: No se puede masa-asignar atributos protegidos

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

I obain 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 

soy No estoy seguro que significa esto. He hecho que el tipo: sea obligatorio, así que si lo elimino, aparece un error sql.

+3

La columna "tipo" se utiliza por defecto por los carriles para las ITS. La mejor solución es cambiar el nombre de la columna de tipo a otra cosa. Una solución no recomendada es agregar el archivo de modelo self.inheritance_column =: some_other_column_that_might_not_exists – bcd

+0

Sí, consulte esta información para evitar el problema de STI al usar la columna 'tipo': http://stackoverflow.com/questions/7134559/rails-use-type-column-without-sti (aunque una mejor opción puede ser cambiar el nombre de la columna). –

+0

Sí, me encontré con este problema. Cambió el nombre de la columna. ¡gracias! – Karan

Respuesta

59

Un par de cosas:

Asignación de masas por lo general significa que pasa atributos en la llamada que crea un objeto como parte de un atributos el hash. Es decir, pasas un montón de atributos en un hash en la llamada que crea el nuevo objeto. Por ejemplo:

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

Sin embargo, rieles incluye algunas reglas básicas de seguridad que significan no todos los atributos se pueden asignar ese modo por defecto. Tienes que especificar cuáles pueden de antemano. Lo hace así:

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

Si no se especifica un atributo es attr_accessible, y se le pasa a crear el objeto, se obtiene el error informados.

Aquí hay más detalles:

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

La alternativa es fijar algunos de los atributos cuando se crea el registro, y establecer otros después - de este modo:

# 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 nombre de columna type porque los rieles se confunden y cree que desea usar la herencia de tabla única (STI), verifique la respuesta a esta pregunta para ver cómo evitarlo: http://guides.rubyonrails.org/

+0

gracias ... funcionó a la perfección! –

+0

¿Qué sucede si intentas crear un padre con muchos hijos a la vez? p.ej; 'Post.create (comments)' – tokhi

0

Here es información sobre qué es la asignación masiva en Rails y por qué la protección está en su lugar. Es bastante fácil moverse cuando realmente quieres 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 
+0

hassle.type = 'sms' muy probablemente generará una clase SMS no existe la excepción – bcd

+0

Quizás. Estoy trabajando bajo el supuesto de que OP sabe lo que está haciendo con STT. – x1a4

7

¿Estás trabajando con Rails 3.2 mientras sigues un tutorial de 3.1 tal como la cuarta edición del programa de desarrollo pragmático "Agile Web Development with Rails"? Luego marque 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 masiva para los modelos Active Record se establece en 'estricto' de forma predeterminada. Comente las líneas apropiadas en estos archivos:

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

... y está listo para seguir aprendiendo.Recuerde que debe dejar esto en efecto cuando la codificación de su primera aplicación de producción :)

+0

"¿Está trabajando con Rails 3.2 mientras sigue un tutorial de 3.1, como la cuarta edición del programa de desarrollo pragmático" Agile Web Development with Rails "? Eso es exactamente lo que estoy haciendo. +1 para solucionar mi problema. –

+0

Esto solucionó mi problema, comenté esta línea: 'config.active_record.mass_assignment_sanitizer =: strict' – mrzmyr

5
  1. Inténtelo: abierta config/application.rb

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

  3. cambio verdadero a falso

Entonces estarás bien.

PD: recuerde reiniciar la consola de rieles.

2

Debería recibir otro error, como este: la columna 'tipo' está reservada para almacenar la clase en caso de herencia. Porque Column 'type' no se debe usar en la base de datos de registros activa.

0

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

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

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

Cuestiones relacionadas