collection_select的多个值

时间:2012-12-31 04:14:51

标签: ruby-on-rails forms

我正在尝试在我的表单中使用以下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>

允许用户在注册时选择两种语言。

我试过这个:

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

无关

有关最佳方法的任何想法吗?

10 个答案:

答案 0 :(得分:7)

尝试,

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

答案 1 :(得分:3)

您可以使用创建字段集合 fields_for
两个选择将具有相同的ID但是 collection_select 采用包含html选项的可选哈希,您可以在其中设置自定义ID。

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

答案 2 :(得分: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][]"}) %>

答案 3 :(得分:1)

由于你在select的name属性中写了“user [language_ids] []”,我不得不假设你想要一个多选框。你应该这样做:

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

肯定不是一个记录完备的功能。

编辑:进一步了解您的示例和一些答案,我想指出一些事项:

  • 您的示例提示“请选择”作为选择框的第一个选项,但是您希望在两个示例中选择“英语”。如果您希望选择预先选择它以及选择框的第一个选项,那么为什么你有提示选项?一个用它来强迫用户选择一些东西。

  • 您在一个答案中写道,您想要多次选择而不是多次选择,这就是为什么您不想要:multiple =&gt;真正的解决我仍然建议你使用它,但也许你真的有一个必要的用例。因此,我建议您直接使用select_tag帮助程序(我认为您不会使用表单标记帮助程序实现这一点):

    select_tag "user[language_ids][]", 
    options_from_collection_for_select(Language.all, "id", "name"), 
    :prompt => true, :id => "user_language_ids"
    
    这里的关键是,多个选择必须有不同的id,你必须明确传递,所以它将在你的手上。

答案 4 :(得分:0)

试试这个:

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

答案 5 :(得分:0)

基本上发送具有相同属性的2个(或更多)字段不起作用,因为params将变为散列:{language_ids: [1], language_ids: [2]}并且由于您具有相同的密钥,因此最后一个将覆盖前一个密钥(或多个)。

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

要解决此问题,您需要创建不同的属性,然后将它们连接在一起。为此,您需要在模型中使用facade属性:

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

但坦率地说,我认为你通过违反惯例来改变你的生活(我会改用复选框)。

答案 6 :(得分:0)

您可以在表格中添加“第二语言”列,然后使其与第一语言列具有相同的内容。

答案 7 :(得分: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 %>

在您的控制器上,在新方法或编辑方法中,您可以执行此操作以接受2种语言

2.times { @user.languages.build }

答案 8 :(得分:0)

首先,您必须编辑您的用户模型:

user.rb

has_many :languages
accepts_nested_attributes_for :languages

接下来生成模型:

$> rails g model language user_id:integer name

language.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 %>

答案 9 :(得分:0)

使用宝石,宝石“茧”

以您要添加字段的模型的形式

  <div class="form-group">
    <%= f.fields_for :photoproducts do |forms_fields| %>
      <% render partial: "shared/photoproducts_fields", locals: {f: forms_fields} %>
    <% end %>
    <%= link_to_add_association('+ Foto', f, :photoproducts, type: "button", class: "btn btn-primary btn-sm") %>
  </div>

(在此示例中,我有一个产品模板,正在向其中添加照片)

,然后在项目根目录的共享文件夹中创建局部文件。

-

项目/共享/ _fotoproduto_fields.html.erb

<div class="nested-fields">
  <%= link_to_remove_association('remove photo', f, type: "button", class: "btn btn-danger btn-sm") %>
  <div class="photoproducts">
    <div class="form-group">
      <label class="control-label"><%= f.label :name %></label>
      <%= f.text_field :name, class: "form-control", type: "text" %>
    </div>
    <div class="form-group">
      <label class="control-label"> photo</label>
      <%= f.file_field :files, class: "form-control" %><br/><br/>
    </div>
  </div>
</div>

通过这种方式,您可以获得更动态的表单

请记住将参数放入嵌套属性的控制器中,并放入create方法(模型的构建)。

例如:@ products.photoproducts.build