2012-12-31 3 views
7

Je suis en train d'avoir le code HTML suivant dans ma forme:valeurs multiples pour collection_select

<select name="user[language_ids][]"> 
    <option value="">Please select</option> 
    <option value="1" selected="selected">English</option> 
    <option value="2">Spanish</option> 
    </select> 

    <select name="user[language_ids][]"> 
    <option value="">Please select</option> 
    <option value="1" selected="selected">English</option> 
    <option value="2">Spanish</option> 
    </select> 

Pour permettre à l'utilisateur de sélectionner deux langues quand il inscrit.

J'ai essayé avec ceci:

<%= f.label :languages %> 
<%= f.collection_select(:language_ids, Language.all, :id, :name) %> 
<%= f.collection_select(:language_ids, Language.all, :id, :name) %> 

Et avec ceci:

<%= f.label :languages %> 
<%= f.collection_select(:language_ids[], Language.all, :id, :name) %> 
<%= f.collection_select(:language_ids[], Language.all, :id, :name) %> 

Après revieweing les réponses, je l'ai essayé avec ceci:

<%= collection_select(:user, :language_ids, Language.all, :id, :name, {}, {:name => 'user[language_ids][]' }) %> 
    <%= collection_select(:user, :language_ids, Language.all, :id, :name, {}, {:name => 'user[language_ids][]' }) %> 

Mais le problème Voici que les deux sélections ont le même ID et aussi, ils ne sont pas associés avec le constructeur de formulaire f

Des idées sur la meilleure façon de le faire?

+0

Voyez-vous les IDs des langues au lieu de leurs noms dans show.html.erb? – uday

+0

Comment les champs de sélection se rapportent-ils au modèle? –

Répondre

5

Essayez,

<%= f.collection_select(:language_ids, Language.all, :id, :name,{}, {:multiple => true}) %> 
+0

Je ne veux pas plusieurs, je veux plusieurs sélections ... Merci bien –

+1

Pas la bonne réponse à la question, mais la bonne réponse pour le mien, alors merci! –

1

Essayez ceci:

<%=select_tag "language_ids[]" options_for_select([['Please select','']]+Language.all.map{|ln|[ln.name,ln.id]})%> 
+0

Ceci est juste une autre façon de faire un collection_select. Ne résout pas la question des auteurs – JustBasti

1

Vous devriez être en mesure de faire quelque chose comme ceci:

<%= f.label :languages %> 
<%= f.collection_select(:language_ids, Language.all, :id, :name, {}, {id => "language_1", :name => "user[language_ids][]"}) %> 
<%= f.collection_select(:language_ids, Language.all, :id, :name, {}, {id => "language_2", :name => "user[language_ids][]"}) %> 
0

Fondamentalement, l'envoi de 2 (ou plus) des champs avec la même attribut ne fonctionne pas, car les paramètres seront transformés en un hachage: {language_ids: [1], language_ids: [2]} et puisque vous avez la même touche la Le premier remplacera le ou les précédents.

{a: 1, a: 2}[:a] #=> 2 

Pour contourner ce problème, vous devez créer différents attributs, puis les concaténer en un. Pour cela, vous aurez besoin des attributs de façade dans votre modèle:

class Language 
    attr_writer :language_one_id, :language_two_id 

    before_save :gather_languages 

    def gather_languages 
    self.language_ids= [language_one_id, language_two_id] 
    end 

    # for the form to display chosen lang (idem with two) 
    def language_id 
    language_ids.first 
    end 
end 

# view/_form 
=f.select :language_one_id, Language.all.map {|l| [l.name, l.id]} 
=f.select :language_two_id, Language.all.map {|l| [l.name, l.id]} 

Mais franchement je pense que vous rendre votre vie plus difficile en allant à l'encontre des conventions ici (j'utiliser des cases à cocher au lieu).

0

Vous pouvez ajouter une colonne "second_language" à votre table, puis lui donner le même contenu que la colonne de la première langue.

0

Vous pouvez utiliser fields_for comme ceci:

<%= form_for @user do |f| %> 
... 
<h2>Languages</h2> 
<%= fields_for :languages do |lang_form| %> 
    <%= lang_form.collection_select :language_id, Language.all, :id, :name %> 
<% end %> 
.. 
<% end %> 

Sur votre contrôleur, dans votre nouveau ou modifier le mode, vous pouvez le faire accepter 2 langues

2.times { @user.languages.build } 
0

Tout d'abord vous devez modifier votre modèle utilisateur:

user.rb

has_many :languages 
accepts_nested_attributes_for :languages 

Suivant générer le modèle:

$> rails g model language user_id:integer name 
langue

.rb

belongs_to :user 

users_controller.rb (probablement 'nouvelle' l'action)

2.times do 
    language = @user.language.build 
end 

_form.html.erb

<%= form_for @user do |f| %> 
    <%= f.fields_for :languages do |lang| %> 
    <%= lang.label :name, "Name" %><br /> 
    <%= lang.select :name, Language.all.collect {|l| [l.name, l.id]}, prompt: 'Please select' %><br /> 
    <%= end %>  
    <p><%= f.submit "Submit" %></p> 
<% end %> 
0

Depuis que vous avez écrit "utilisateur [language_ids] []" dans l'attribut name de votre select, je suis forcé de supposer que vous voulez une boîte de sélection multiple. Vous devriez faire ceci:

f.collection_select (:language_ids, Language.all, :id, :name, 
{:prompt => true}, {:multiple => true}) 

Ce n'est pas une fonctionnalité très bien documentée, c'est certain.

EDIT: En regardant plus sur votre exemple et quelques-unes des réponses, je voudrais souligner quelques petites choses:

  • Votre exemple a l'invite « S'il vous plaît sélectionner » comme première option de la boîte de sélection , mais alors vous voulez que l'anglais soit "sélectionné dans vos deux exemples." Si vous voulez qu'une option soit présélectionnée et qu'elle soit la première option de la boîte de sélection, alors pourquoi avez-vous l'option d'invite? pour forcer l'utilisateur à choisir quelque chose

  • Vous avez écrit dans une réponse que vous voulez plusieurs sélections au lieu d'un multiple sélectionner, rea fils pourquoi vous ne voulez pas la: multiple => solution vraie. Je vous recommande toujours de l'utiliser, mais peut-être que vous avez vraiment un cas d'utilisation nécessaire. Par conséquent, je vous recommande d'utiliser l'aide de select_tag directement (je ne pense pas que vous allez réaliser que avec des aides de balise form):

    select_tag "user[language_ids][]", 
    options_from_collection_for_select(Language.all, "id", "name"), 
    :prompt => true, :id => "user_language_ids" 
    

    clé ici est, les mutiple choisit doivent avoir des papiers d'identité, qui vous devrez passer explicitement, donc ce sera sur vos mains.

3

Vous pouvez créer une collection de champs en utilisant fields_for.
Les deux select auront le même id mais collection_select prend une options de hachage contenant options html où vous pouvez définir un id personnalisé.

<%= f.fields_for :language_ids do |language| %> 
    <%= language.collection_select(nil, Language.all, :id, :name, 
     {include_blank: "Please select", selected: 1}, 
     {id: :user_language_id_1}) %> 
    <%= language.collection_select(nil, Language.all, :id, :name, 
     {include_blank: "Please select", selected: 1}, 
     {id: :user_language_id_2}) %> 
<% end %> 

génère la sortie suivante:

<select id="user_language_id_1" name="user[language_ids][]"> 
    <option value="">Please select</option> 
    <option value="1" selected="selected">English</option> 
    <option value="2">Spanish</option> 
</select> 

<select id="user_language_id_2" name="user[language_ids][]"> 
    <option value="">Please select</option> 
    <option value="1" selected="selected">English</option> 
    <option value="2">Spanish</option> 
</select>