0

Controller: projects_controller.rb

def new
    @project = Project.new
    @project.repositories.build
end

def edit
  @project = Project.find(params[:id])
end

Model: project_sub_type.rb

class ProjectSubType < ActiveRecord::Base
  has_many :repositories, :dependent => :destroy
  accepts_nested_attributes_for :repositories
end

View: _form.html.erb

<%= form_for @project, :html => {:class => 'project'} do |f| %>
  <%= f.label :name, "Project name" %>
  <%= f.text_field :name %>
      <%= f.fields_for :repositories do |ff| %>
        <%= ff.check_box :repos_name, {} , "svn_software", nil %> Svn Software
      <% end %>
      <%= f.fields_for :repositories do |ff| %>
        <%= ff.check_box :repos_name, {} , "git_software", nil %> Git Software
      <% end %>
<%= f.submit "Save"%>

edit.html.erb

<h2>Edit project</h2>
<%= render 'form' %>

Question: During create it creates the checkbox like this

<input type="checkbox" value="svn_software" name="project[repositories_attributes][0][repos_name]" id="project_repositories_attributes_0_repos_name"> 
<input type="checkbox" value="git_software" name="project[repositories_attributes][1][repos_name]" id="project_repositories_attributes_1_repos_name"> 

And it works perfectly for me. But during edit it creates 2 fields extra:

<input type="checkbox" value="svn_software" name="project[repositories_attributes][0][repos_name]" id="project_repositories_attributes_0_repos_name"> 
<input type="checkbox" value="svn_software" name="project[repositories_attributes][1][repos_name]" id="project_repositories_attributes_1_repos_name"> 
<input type="checkbox" value="git_software" name="project[repositories_attributes][2][repos_name]" id="project_repositories_attributes_2_repos_name"> 
<input type="checkbox" value="git_software" name="project[repositories_attributes][3][repos_name]" id="project_repositories_attributes_3_repos_name"> 

And also creates a hidden field as below:

<input type="hidden" value="51" name="project[repositories_attributes][0][id]" id="project_repositories_attributes_0_id"> to .. 3

Can someone please point out my mistake. And the same problem exist if I use 1 fields_for and loop though an array.

Can anyone please help.

Thanks in advance

  • can u show me edit.html.erb??..also check the params during create ..you must get something like this.. { project: { name: 'Test project 1', repositories_attributes: ["0"=> {{:repos_name=>"svn_software" },"1"=>{:repos_name=>"git_software" }}, ] }} – Milind Aug 13 '14 at 12:01
  • @Milind: Yes during create I am exactly getting similar params. Check my updated answer for edit. –  Aug 13 '14 at 12:03

1 Answers1

0

Reference to http://apidock.com/rails/v3.2.13/ActionView/Helpers/FormHelper/fields_for

Your code will cause duplication result, because The block given to the nested fields_for call will be repeated for each instance in the collection, so you have to :

<%= form_for @project, :html => {:class => 'project'} do |f| %>
  <%= f.label :name, "Project name" %>
  <%= f.text_field :name %>
    <% @project.repositories.each do |r| %>
      <%= f.fields_for :repositories, r do |ff| %>
        <%= ff.check_box :repos_name, {} , r.repos_name, true %><%=r.repos_name%>
      <% end %>
    <% end %>
<%= f.submit "Save"%>

But when create, you should fill the check_box not include in repositories. So you could:

<%= form_for @project, :html => {:class => 'project'} do |f| %>
  <%= f.label :name, "Project name" %>
  <%= f.text_field :name %>
    <% @project.repositories.each do |r| %>
      <%= f.fields_for :repositories, r do |ff| %>
        <%= ff.check_box :repos_name, {} , r.repos_name, true %><%=r.repos_name%>
      <% end %>
    <% end %>
    <% (['svn_software','git_software'] - @project.repositories.map(& :repos_name)).each do |name| %>
      <%= ff.check_box :repos_name, {} , name, nil %><%=name%>
    <% end %>
<%= f.submit "Save"%>
Jaugar Chang
  • 3,176
  • 2
  • 13
  • 23