2016-11-07 4 views
1

J'ai mon problème, un peu résolu, mais je pense que c'est un peu maladroite, donc j'espère obtenir un meilleur moyen, ainsi qu'une meilleure compréhension de ce qui se passe ici.Rails select_tag méthode non définie `map 'pour nil: NilClass

_form.html.erb:

<%= select_tag(:category_id, options_for_select(@categories), :prompt => "Select one!") %> 

products_controller.rb:

def new 
    @product = Product.new 
    @categories = Category.all.map { |c| [ c.name, c.id ] } 
end 

Si l'utilisateur soumet le formulaire sans sélectionner l'une des select_tag options qu'il reçoit une erreur undefined method 'map' for nil:NilClass.

Je sais que cela vient depuis mon @categories est nil, mais je ne peux pas comprendre comment éviter cela ..?

Ma solution finale, qui travaille:

<%= select_tag(:category_id, options_for_select(@categories || Category.all.map { |c| [ c.name, c.id ] }), :prompt => "Select one!") %> 

Mais je pense qu'il ya une meilleure façon. Je pense aussi, qu'en attribuant une valeur par défaut select_tag avec :selected pourrait fonctionner aussi bien, mais je ne pourrais pas la mettre en œuvre avec ma connaissance de la syntaxe Ruby ...

+2

Lorsque vous soumettez votre formulaire 'méthode create' est exécutée assurez-vous d'initialiser le' @ categories' dans la méthode '' @ create' si product.save' retourne false. – dnsh

+0

Oh, c'est gentil. Merci de répondre. J'ai ajouté 'if @ product.save == false @categories = Category.all.map {| c | [c.name, c.id]} fin' pour créer une action et il semble que cela fonctionne bien. Triste que je ne peux pas marquer votre commentaire comme une réponse ... –

+1

Commentaire @dnsh fonctionne très bien, mais la réponse de @SnehaT est la meilleure façon de procéder, car il se débarrasse de la nécessité de «@ catégories» ... de préférence vous devrait avoir aussi peu de variables d'instance que possible pour une vue, idéalement une seule. – SteveTurczyn

Répondre

3

S'il vous plaît essayer cette façon de select_tag:

select_tag(:category_id, options_from_collection_for_select(Category.all, :id, :name), include_blank: "Select Category") 

Faites-moi savoir si vous rencontrez un problème ..

+0

Oh c'est encore mieux. Je pensais qu'éviter une boucle supplémentaire serait mieux. Merci! –

0

Oui vous pouvez aller avec la méthode d'aide que d'utiliser Category.all dans chaque vue

def categories 
    Category.all.map { |c| [ c.name, c.id ] } 
end 

et l'utiliser dans les vues

<%= select_tag(:category_id, 
       options_for_select(categories), 
       include_blank: "Select Category") %> 
+0

toujours la même erreur pour une classe nulle. –