7

フォームに次の HTML コードを含めようとしています。

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

ユーザーがサインアップ時に 2 つの言語を選択できるようにするため。

私はこれを試しました:

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

また、これで:

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

答えを見直した後、私はこれを試しました:

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

ただし、ここでの問題は、両方の選択が同じ ID を持ち、フォーム ビルダーに関連付けられていないことです。f

そうするための最良の方法について何か考えはありますか?

4

10 に答える 10

8

試す、

<%= f.collection_select(:language_ids, Language.all, :id, :name,{}, {:multiple => true}) %>
于 2012-12-31T06:00:06.600 に答える
3

を使用して、フィールドのコレクションを作成できます fields_for
2 つの選択は同じ ID を持ち collection_select ますが、カスタム ID を設定できる html オプションを含むオプションのハッシュを取ります。

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

次の出力が生成されます。

<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>
于 2013-01-10T18:55:39.767 に答える
2

selectのname属性に「user[language_ids][]」と書いたので、複数選択ボックスが必要だと思わざるを得ません。これを行う必要があります:

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

確かに、十分に文書化された機能ではありません。

編集:あなたの例といくつかの答えをさらに見て、いくつか指摘したいと思います:

  • あなたの例には、選択ボックスの最初のオプションとして「選択してください」というプロンプトがありますが、両方の例で「選択してください」というプロンプトが表示されます。選択ボックスの場合、なぜプロンプト オプションがあるのですか? 1 つは、ユーザーに何かを選択させるために使用します。

  • 複数選択ではなく複数選択が必要であると1つの回答に書いたので、 :multiple => true ソリューションが必要ない理由です。それでも使用することをお勧めしますが、本当に必要なユースケースがあるかもしれません。したがって、select_tag ヘルパーを直接使用することをお勧めします (フォーム タグ ヘルパーでは実現できないと思います)。

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

    ここで重要なのは、複数の選択には異なるIDが必要であり、明示的に渡す必要があるため、それはあなたの手に委ねられます。

于 2013-01-10T16:01:12.820 に答える
1

次のようなことができるはずです。

<%= 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][]"}) %>
于 2013-01-08T17:00:43.110 に答える
0

これを試して:

<%=select_tag "language_ids[]" options_for_select([['Please select','']]+Language.all.map{|ln|[ln.name,ln.id]})%>
于 2013-01-01T17:02:22.577 に答える
0

「second_language」列をテーブルに追加して、最初の言語列と同じ内容にすることができます。

于 2013-01-10T13:07:01.450 に答える
0

まず、ユーザー モデルを編集する必要があります。

user.rb

has_many :languages
accepts_nested_attributes_for :languages

次にモデルを生成します。

$> rails g model language user_id:integer name

言語.rb

belongs_to  :user

users_controller.rb (おそらく「新規」アクション)

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 %>
于 2013-01-10T15:49:53.377 に答える
0

次のように fields_for を使用できます。

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

コントローラーの new メソッドまたは edit メソッドで、これを実行して 2 つの言語を受け入れることができます。

2.times { @user.languages.build }
于 2013-01-10T13:24:57.563 に答える
0

params が hash に変換されるため、基本的に同じ属性を持つ 2 つ (またはそれ以上) のフィールドを送信しても機能しません。{language_ids: [1], language_ids: [2]}また、同じキーを持っているため、最後のフィールドが前のフィールドを上書きします。

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

この問題を回避するには、異なる属性を作成してから、それらを 1 つに連結する必要があります。このためには、モデルにファサード属性が必要です:

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

しかし、率直に言って、ここで慣例に反することであなたの人生を難しくしていると思います(代わりにチェックボックスを使用します).

于 2013-01-09T14:26:59.597 に答える