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>

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

我试过这个:

<%= 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
这两个选择将具有相同的 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>
于 2013-01-10T18:55:39.767 回答
2

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

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

当然,这不是一个非常有据可查的功能。

编辑:进一步查看您的示例和一些答案,我想指出一些事情:

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

  • 您在一个答案中写道,您想要多选而不是多选,这是您不想要 :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

基本上发送具有相同属性的 2 个(或更多)字段是行不通的,因为 params 将被转换为哈希:{language_ids: [1], language_ids: [2]}并且由于您具有相同的键,因此最后一个将覆盖前一个。

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

为了规避这个问题,您需要创建不同的属性,然后将它们连接在一起。为此,您需要模型中的外观属性:

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 回答
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 }
于 2013-01-10T13:24:57.563 回答
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

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

用户.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

使用宝石,宝石“茧”

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

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

这样你得到一个更动态的形式

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

例如:@products.photoproducts.build

于 2019-05-09T11:28:54.497 回答