web-dev-qa-db-fra.com

ActiveModel :: MassAssignmentSecurity :: Error: impossible d'attribuer en masse des attributs protégés

Si j'essaie d'exécuter le code suivant:

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

J'obtiens l'erreur suivante:

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

Je ne suis pas sûr de ce que cela signifie. J'ai rendu le: type obligatoire, donc si je le supprime, j'obtiens une erreur sql.

26
Karan

Quelques choses:

L'affectation de masse signifie généralement la transmission d'attributs dans l'appel qui crée un objet dans le cadre d'un hachage d'attributs . Autrement dit, vous passez un tas d'attributs dans un hachage dans l'appel qui crée le nouvel objet. Par exemple:

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

Cependant, Rails inclut des règles de sécurité de base qui signifient que tous les attributs ne peuvent pas être attribués de cette façon par défaut . Vous avez pour spécifier ceux qui peuvent au préalable. Vous le faites comme ceci:

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

Si vous ne spécifiez pas un attribut est attr_accessible, et vous le transmettez pour créer l'objet, vous obtenez l'erreur que vous avez publiée.

Voici plus de détails:

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

L'alternative consiste à définir certains des attributs lors de la première création de l'enregistrement et à définir d'autres après - comme ceci:

# 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

De plus, si vous rencontrez des problèmes avec l'utilisation du nom de colonne type car Rails devient confus et pense que vous souhaitez utiliser l'héritage de table unique (STI), vérifiez la réponse à cette question pour voir comment le contourner: http://guides.rubyonrails.org/

63
Kevin Bedell

Travaillez-vous avec Rails 3.2 tout en suivant un didacticiel 3.1 tel que le "Développement Web Agile avec Rails" du Pragmatic Programmer? Vérifiez ensuite http://guides.rubyonrails.org /3_2_release_notes.html .

Votre problème est que de Rails 3.1 à 3.2, la vérification de la protection des affectations de masse pour les modèles Active Record est définie par défaut sur "stricte". Mettez en commentaire les lignes appropriées dans ces fichiers:

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

... et vous êtes prêt à continuer à apprendre. N'oubliez pas de laisser cela en vigueur lors du codage de votre première application de production :)

7
LANerd
  1. Veuillez essayer: ouvrez config/application.rb

  2. Localisez la ligne de config.active_record.whitelist_attributes = true

  3. Changer vrai en faux

Alors tout ira bien.

PS: n'oubliez pas de redémarrer la console Rails.

5
Mr. Pei

Vous devriez obtenir une autre erreur, comme celle-ci: la colonne 'type' est réservée au stockage de la classe en cas d'héritage. Parce que la colonne 'type' ne doit pas être utilisée dans la base de données d'enregistrement active.

2
Richardlonesteen

Je n'utilise pas whitelist_attributes puisque les cas d'utilisation où je veux autoriser l'affectation de masse sont pour ma logique interne et généralement pas directement dans les actions Controller for CRUD. Je suggère d'utiliser des paramètres puissants dans ces cas. Mais lorsque vous souhaitez activer l'affectation en masse pour un modèle spécifique, vous le faites

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

Cela définit essentiellement attr_protected pour vider le tableau ([])

1
Haris Krajina

Ici est quelques informations sur ce que l'affectation de masse dans Rails est, et pourquoi la protection est en place. Il est assez facile de se déplacer lorsque vous voulez vraiment assigner un attribut protégé, mais cela prend quelques lignes supplémentaires.

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