2010-11-16 32 views
0

Je viens juste de commencer à apprendre les rails et le rubis, alors s'il vous plaît, supportez-moi si c'est trop bête.Rails: impossible d'assigner la masse à ces attributs protégés en essayant de définir le type STI pendant la création

Il existe plusieurs types d'AppModule différents dans mon application, qui ont un comportement différent mais des données similaires. Je les enregistre donc en utilisant l'héritage de table unique.

Cependant, en essayant permettre à l'utilisateur de sélectionner explicitement le type qu'ils veulent app_modules/new.html.erb je reçois l'avertissement WARNING: Can't mass-assign these protected attributes: type. Voici le code correspondant:

<% form_for(@app_module) do |f| %> 
    <%= f.error_messages %> 

    <p> 
    <%= f.label :type %><br /> 
    <%= f.select(:type, options_from_collection_for_select(AppModule.subclasses().map{ |c| c.name}, 'to_s', 'to_s')) %> 
    </p> 

    <%= f.submit 'Create' %> 
<% end %> 

J'ai essayé de placer explicity dans le fichier attr_accessible :type modèle, mais il ne fonctionne pas

J'utilise des rails 2.3.8 et 1.8.7 rubis.

Toute aide grandement appréciée, merci ...

Répondre

6

Vous ne devriez jamais avoir à définir l'attribut de type manuellement. Utilisez les sous-classes que vous avez créées à la place.

model = params[:app_module].delete(:type).constantize 
model = AppModule unless model.is_a?(AppModule) 
@app_module = model.new(params[:app_module]) 
+0

Ceci est vraiment pratique avec STI. –

+0

Bien sûr, vous ajouteriez une vérification pour vous assurer que seuls les types que vous autorisez spécifiquement peuvent être créés de cette manière. Ce code permettrait à un utilisateur de créer n'importe quelle classe qu'il aime dans votre application et de lui fournir les paramètres d'initialisation de son choix (si je ne me trompe pas). –

+0

@BrendonMuir Oui c'est un bon point, vous devriez toujours désinfecter les params qui exécutent du code comme celui-ci. Je vais ajouter une ligne pour cela. –

1

Ajouter ceci à votre classe de base:

def attributes_protected_by_default 
    super - [self.class.inheritance_column] 
    end 

Je recommande la méthode d'Adam à moins que vous avez affaire à une liste mixte.

0

J'ai juste besoin de commenter la ligne suivante dans mon 'config/application.rb' pour résoudre ce problème.

# config.active_record.whitelist_attributes = true