ruby-on-rails - sirve - variable de clase en ruby
"ADVERTENCIA: no se puede asignar en masa los atributos protegidos" (5)
He usado técnicas RESTful para generar un modelo (de hecho, estoy usando la gema Devise, que lo hace por mí), y he agregado nuevos campos llamados first_name y last_name al modelo. La migración fue bien. Agregué attr_accessor: first_name,: last_name al modelo y esperaba que simplemente funcionara. Pero cuando trato de asignar en masa nuevas instancias con Doctor.create ({: first_name => "MyName"}) etc., recibo errores que dicen que no puedo asignar en masa los atributos protegidos.
Pensé que el objetivo de usar attr_accessor era evitar la protección de los campos de un modelo. ¿Puedes ayudarme a entender este mensaje?
Editar: oh, y por cierto los registros tampoco se crean. Pensé que deberían ser, ya que esto es solo una advertencia, pero no están en la base de datos.
Edit2: aquí está mi modelo
class Doctor < User
has_many :patients
has_many :prescriptions, :through=> :patients
validates_presence_of :invitations, :on => :create, :message => "can''t be blank"
attr_accessor :invitations
end
y el esquema, que no tiene el primer nombre y el último nombre porque se crean en la tabla de usuarios, que es el antecesor de los médicos. Usé herencia de mesa única.
create_table :doctors do |t|
t.integer :invitations
t.timestamps
end
y esta es la migración para cambiar la tabla de usuarios
add_column :users, :first_name, :string
add_column :users, :last_name, :string
add_column :users, :type, :string
EDITAR: aquí está el archivo semilla. No incluyo el método truncate_db_table, pero funciona.
%w{doctors patients}.each do |m|
truncate_db_table(m)
end
Doctor.create(:invitations=>5, :email=>"[email protected]", :first_name=>"Name", :last_name=>"LastName")
Patient.create(:doctor_id=>1, :gender=>"male", :date_of_birth=>"1991-02-24")
Agregue attr_accessible : variable1, variable2
a su archivo de ruta de tabla.
De acuerdo con la respuesta de @Robert Speicher. Pero recomendaré encarecidamente que use el parámetro Strong en lugar de attr_accessible
para protegerlo de la asignación masiva.
¡Aclamaciones!
No confundas attr_accessor
con attr_accessible
. Accessor está integrado en Ruby y define un método getter - model_instance.foo # returns something
- y un método setter - model_instance.foo = ''bar''
.
Accesible está definido por Rails y hace que el atributo se attr_protected
la masa (hace lo contrario a attr_protected
).
Si first_name
es un campo en la tabla de la base de datos de su modelo, Rails ya ha definido getters y setters para ese atributo. Todo lo que necesita hacer es agregar attr_accessible :first_name
.
No use attr_accessor aquí. ActiveRecord los crea automáticamente en el modelo. Además, ActiveRecord no creará un registro si se produce un error de validación o asignación masiva.
EDITAR: no necesita una tabla de médicos, necesita una tabla de usuarios con una columna de tipo para gestionar la herencia de tablas únicas de Rails. Las invitaciones estarán en la tabla de usuarios. Ah, veo en tu ejemplo de código agregado que tienes que escribir en los usuarios. Deshágase de la mesa de médicos, envíe invitaciones a los usuarios y creo que debería estar bien. También deshazte del attr_accessor. Innecesario.
Tenga en cuenta que Rails STI utiliza la misma tabla para todas las clases y subclases de un modelo en particular. Todos sus registros médicos serán filas en la tabla de usuarios con un tipo de ''doctor''
EDITAR: Además, ¿está seguro de que solo desea validar la presencia de invitaciones en la creación y no las actualizaciones?
Para hackear su aplicación juntos de una manera insegura totalmente no apta para el modo de producción:
Vaya a /config/application.rb Desplácese hacia abajo, hacia el final, donde encontrará
{config.active_record.whitelist_attributes = true}
Establecerlo en falso.
EDITAR / por cierto (después de 4 meses de trabajo intensivo en rubí, incluido un taller de 11 semanas): DHH cree que, para novatos (sus palabras), " comenzar a funcionar" es más importante que "muy seguro".
SE ACONSEJA: Aunque esta respuesta (la primera en , creo) ahora está en +6, ha sido tan baja como -4 en su historia, el significado de eso es que muchos desarrolladores de carriles experimentados se sintieron muy apasionados por no querer tu para hacer esto
ACTUALIZACIÓN: 3 años más tarde, otra forma de hacer esto - una vez más, no es seguro, pero es mejor que la solución anterior, probablemente porque tiene que hacerlo para cada modelo
class ModelName < ActiveRecord::Base
column_names.each do |col|
attr_accessible col.to_sym
end
...
end