67 votes

"AVERTISSEMENT: impossible de masse-assigner des attributs protégés"

J'ai utilisé Reposant techniques pour générer un modèle (en fait, je suis à l'aide de Concevoir des gem, qui n'a que pour moi), et j'ai ajouté de nouveaux champs first_name et last_name pour le modèle. La Migration s'est bien passé. J'ai ajouté attr_accessor :prenom, :nom du modèle et devrait il serait juste de travail. Mais quand j'essaie de masse attribuer de nouvelles instances avec le Médecin.créer({:prenom=>"Monnom"}) etc. J'obtiens des erreurs en disant: je ne peux pas en masse attribuer des caractéristiques protégées.

Je pensais que tout le point de l'utilisation de attr_accessor était d'obtenir autour de la protectedness des champs d'un modèle. Pouvez-vous m'aider à faire sens de ce message?

Edit: oh, et par la manière dont les documents ne sont pas créés. Je pense qu'ils devraient être, puisque c'est juste un avertissement, mais ils ne sont pas sur la base de données.

Edit2: voici mon modèle

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

et le schéma, qui n'a pas la first_name et last_name parce qu'ils sont créés dans la table des utilisateurs, qui est l'ancêtre des médecins. Je l'ai utilisé seul héritage de table.

create_table :doctors do |t|
  t.integer :invitations

  t.timestamps
end

et c'est la migration de modifier la table des utilisateurs

add_column :users, :first_name, :string
add_column :users, :last_name, :string
add_column :users, :type, :string

EDIT: voici la graine de fichier. Je ne suis pas y compris le truncate_db_table méthode, mais ça marche.

%w{doctors patients}.each do |m|
  truncate_db_table(m)  
end  

Doctor.create(:invitations=>5, :email=>"email@gmail.com", :first_name=>"Name", :last_name=>"LastName")
Patient.create(:doctor_id=>1, :gender=>"male", :date_of_birth=>"1991-02-24")

140voto

Robert Speicher Points 8292

Ne pas confondre attr_accessor avec attr_accessible. Accesseur est construit en Ruby et définit une méthode de lecture - model_instance.foo # returns something - et une méthode de définition - model_instance.foo = 'bar'.

Accessible est défini par les Rails et rend l'attribut de masse cessible (à l'opposé de l' attr_protected).

Si first_name est un champ dans votre modèle de table de base de données, puis les Rails a déjà défini des getters et setters pour cet attribut. Tout ce que vous devez faire est d'ajouter attr_accessible :first_name.

11voto

boulder_ruby Points 6257

Pour pirater votre app de façon non sécurisée totalement inapte pour le mode de production:

Allez dans /config/application.rb faites Défiler vers la fin, où vous trouverez

{config.active_record.whitelist_attributes = true}

Affectez la valeur false.

MODIFIER/btw (après 4 mois de rubis intense travail dont 11 semaine d'atelier): DHP est d'avis que, pour les noobies (ce sont ses mots), "up and running" est plus important que de "très sûr".

À noter: même Si cette réponse (mon tout premier sur stackoverflow, je pense) est maintenant à +6, il a été aussi faible qu'-4 dans son histoire, le sens de être un beaucoup d'expérience rails développeurs ont très passionné au sujet de ne pas vouloir le faire.

2voto

Dave Sims Points 2982

N'utilisez pas de attr_accessor ici. ActiveRecord crée ces automatiquement sur le modèle. Aussi, ActiveRecord ne va pas créer un enregistrement si une validation ou de la masse de cession d'erreur est levée.

EDIT: Vous n'avez pas besoin de médecin, de table, vous avez besoin d'une table des utilisateurs avec une colonne de type pour gérer les Rails Unique de l'Héritage de Table. Les invitations seront sur la table des utilisateurs. Ah, je vois dans votre exemple de code que vous avez tapez sur les utilisateurs. Se débarrasser des médecins table, déplacez les invitations sur les utilisateurs, et je pense que vous devriez être ok. Aussi se débarrasser de la attr_accessor. N'est pas nécessaire.

Gardez à l'esprit que les rails STI utilise la même table pour toutes les classes et sous-classes d'un modèle particulier. Tous de votre Médecin dossiers seront rangées dans la table des utilisateurs avec un type de 'docteur'

EDIT: Aussi, êtes-vous sûr que vous ne voulez valider la présence des invitations sur la création, et non pas les mises à jour?

2voto

Aneez Points 3

Ajouter attr_accessible : variable1, variable2 de votre tableau de fichier de route.

0voto

Manish Shrivastava Points 4380

D'accord avec @Robert Speicher réponse, Mais je vous la recommandons fortement que Vous devriez utiliser Forte paramètre au lieu de attr_accessible pour les protéger de la masse asignment.

Cheers!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X