fields_for表示使用数组的has_many关联



控制器: project_sub_types_Controller.rb

  def new
    @svn_repos = ['svn_software','svn_hardware']
    @project_sub_type = ProjectSubType.new
    @project_sub_type.repositories.build
  end

型号:project_sub_type.rb

class ProjectSubType < ActiveRecord::Base
  belongs_to :project_type
  has_many :repositories, :dependent => :destroy
  accepts_nested_attributes_for :repositories
  def repositories_attributes=(attributes)
    # Process the attributes hash
  end
end

视图:_form.html.erb

<%= form_for @project_sub_type, :html => {:class => 'project_subtype_form'} do |f| %>
  <%= f.label :name, "Project sub type name" %>
  <%= f.text_field :name %>
  <%= f.fields_for :repositories do |ff| %>
      <%= ff.label :select_svn_repositories, "Select SVN repositories" %> 
      <% @svn_repos.each do |repos| %>
          <%= ff.check_box :repos_name, {}, "#{repos}", nil %>
          <%= h repos -%>
      <% end %>
<%= f.submit "Save"%>

fields_form检查元素:

<input id="project_sub_type_repositories_attributes_0_repos_name" type="checkbox" value="svn_software" name="project_sub_type[repositories_attributes][0][repos_name]">
svn_software
<input id="project_sub_type_repositories_attributes_0_repos_name" type="checkbox" value="svn_hardware" name="project_sub_type[repositories_attributes][0][repos_name]">
svn_hardware 

在提交表格params = "repositories_attributes"=>{"0"=>{"repos_name"=>"svn_hardware"}}}之后,即使在检查了两个复选框之后,它也在使用最后选择的复选框"svn_hardware">

[EDIT]

所需输出:我的最终输出应该是用户选择的,所以在这种情况下,在我的提交后params="repositories_attributes"=>{"0"=>{"repos_name"=>"svn_software"}{"1"=>{"repos_name"=>"svn_hardware"}}中应该是这样

我认为两者都有0作为前缀的原因是您只指定了一个repository对象,而您的数组(@svn_repos(包含两个

然而,如果你改为这样做:

# controller (inside new method)
@project_sub_type.repositories.build # 1 new object
@project_sub_type.repositories.build # 2 new objects

然后,您必须在_form部分中对这两个对象进行迭代,并将名称映射到@svn_repos数组。不过,我更喜欢这种解决方案:

# controller (inside new method)
@project_sub_type.repositories.build name: 'svn_software'
@project_sub_type.repositories.build name: 'svn_hardware'

然后,使用模型的name属性而不是数组的属性,对分部中的存储库进行迭代。

正如Nicolay所解释的,您之所以拥有0,是因为您曾经构建过这个@project_sub_type.repositories.build对象。代码中的所有内容都是正确的。但如果你必须选择多个复选框,那么根据DOCS

视图中:_form.html.erb更改

<%= ff.check_box :repos_name, {}, "#{repos}", nil %>

TO

<%= ff.check_box :repos_name, {:multiple => true}, "#{repos}", nil %>

现在,您应该能够在提交后看到params,如下所示:

=>{"0"=>{"repos_name"=>["svn_software","svn_hardware"]}}