2012-12-31 14 views
7

Staram się mieć następujący kod HTML w moim formularzu:Wiele wartości 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> 

Aby umożliwić użytkownikowi wybrać dwa języki, kiedy podpisuje się.

Próbowałem z tym:

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

A także z tego:

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

Po revieweing odpowiedź, próbowałem z tym:

<%= 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][]' }) %> 

Ale problem tutaj oba selekcje mają ten sam identyfikator, a także nie są powiązane z konstruktorem formularzy f

Jakieś przemyślenia na najlepszy sposób na zrobienie tego?

+0

widzisz identyfikatory języków zamiast ich nazw w show.html.erb? – uday

+0

W jaki sposób pola wyboru odnoszą się do modelu? –

Odpowiedz

5

spróbować

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

Nie chcę wielu, chcę kilka wyborów ... Dziękujemy jednak –

+1

Nie jest to właściwa odpowiedź na pytanie, ale właściwa odpowiedź dla mnie, dzięki! –

1

Spróbuj to:

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

To jest po prostu inny sposób robienia collection_select. Nie rozwiązuje pytania autorów – JustBasti

1

Powinieneś być w stanie zrobić coś takiego:

<%= 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

zasadzie wysyłania 2 (lub więcej) pól mających ten sam atrybut nie działa, ponieważ parametry zostaną przekształcone w skrót: {language_ids: [1], language_ids: [2]}, a ponieważ masz ten sam klucz st jeden zastąpi poprzednie (poprzednie).

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

Aby obejść ten problem, należy utworzyć różne atrybuty, a następnie połączyć je w jeden. Do tego trzeba atrybuty elewacji w modelu:

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]} 

Ale szczerze mówiąc myślę, że robisz swoje życie ciężej przechodząc przed konwencjami tutaj (ja zamiast użyć pól wyboru).

0

Możesz dodać kolumnę "second_language" do swojej tabeli, a następnie sprawić, by miała taką samą treść jak kolumna pierwszego języka.

0

Można użyć fields_for tak:

<%= 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 %> 

Na kontrolerze, w swoim nowym lub edytować metodę, można to zrobić, aby przyjąć 2 języków

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

Przede wszystkim trzeba edytować swój model obsługi:

user.rb

has_many :languages 
accepts_nested_attributes_for :languages 

Następny wygenerować model:

$> rails g model language user_id:integer name 

język.rb

belongs_to :user 

users_controller.rb (prawdopodobnie w 'nowych' akcji)

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

Ponieważ napisałem "user [language_ids] []" w atrybut nazwy Twojego wyboru, jestem zmuszony założyć, że chcesz pole wyboru wielokrotnego. Powinieneś to zrobić:

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

Niezbyt dobrze udokumentowana funkcja, na pewno.

EDIT: Patrząc dalej na przykład, a niektóre z odpowiedzi, chciałbym zwrócić uwagę na kilka rzeczy:

  • Twój przykład ma monit „Wybierz” jako pierwszej opcji w polu wyboru , ale potem chcesz, aby angielski był "wybrany w obu przykładach. Jeśli chcesz, aby opcja była wstępnie wybrana, która jest również pierwszą opcją pola wyboru, to dlaczego masz opcję pytania? aby zmusić użytkownika do wyboru czegoś:

  • W jednej odpowiedzi napisałeś, że chcesz wielokrotnego wyboru zamiast wielokrotnego wyboru, rea synu, dlaczego nie chcesz: multiple => true solution. Wciąż zalecałbym, abyś z niego korzystał, ale może naprawdę potrzebujesz niezbędnego przypadku. Dlatego polecam Ci użyć pomocnika select_tag bezpośrednio (I nie sądzę, że można osiągnąć z pomocników forma znaczników):

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

    Kluczem tutaj jest, że mutiple wybiera mieć różne identyfikatory, które będziesz musiał przekazać jawnie, więc będzie na twoich rękach.

3

Można utworzyć kolekcję pól za pomocą fields_for.
Dwa wybrane mają ten sam identyfikator, ale collection_select przyjmuje opcjonalne opcje hashml z hashami, w których można ustawić niestandardowy identyfikator.

<%= 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 %> 

generuje następujący wynik:

<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>