在Rails中通过1个表单编辑嵌套集合

我正在尝试创建一个表单,我可以在一个视图中单独编辑集合中的所有项目。 我使用Railscast#198( http://railscasts.com/episodes/198-edit-multiple-individually )作为一般指南,但没有包含复选框,因为我只想一次编辑集合中的每个项目(不是选择)哪些要编辑)。 根据我目前的情况,表单显示正确,但我在提交时遇到此类错误:

ArgumentError in ProceduresController#update_procedures wrong number of arguments (0 for 2). Parameters: {"utf8"=>"✓", "_method"=>"put", "authenticity_token"=>"i9kB+uGlguerjxl0VHy1dRyMY5HrZQdILVuM79Df4Z4=", "procedures"=>{"1"=>{"description"=>"Example1"}, "2"=>{"description"=>"Example2"}}, "commit"=>"Submit", "comp_id"=>"1"} 

请告诉我这里缺少的东西:

在我的控制器中:

 def edit_procedures @comp = Comp.find(params[:comp_id]) @procedures = @comp.procedures.all end def update_procedures @comp = Comp.find(params[:comp_id]) @procedures = @comp.procedures.update.(params[:procedures].keys, params[:procedures].values).reject { |p| p.errors.empty? } end 

在我的路线:

 resources :comps do resources :procedures do collection do get 'edit_procedures' put 'update_procedures' end end end 

在我看来:

  :put do %>         

我也尝试将’edit_procedures’方法从GET更改为POST,但后来我收到了这个错误:未知动作,无法找到ProceduresController的动作’show’。

谢谢您的帮助。

更新:

实际上,我刚才想出的这个解决方案要好得多。 我只是将表单更改为此(除了下面列出的控制器的更改):

 <%= form_for @comp, :url => 'update_procedures', :method => :put do |f| %> <%= f.fields_for :procedures do |g| %> <%= g.text_field :description %> <% end %> <%= f.submit "Update procedures" %> <% end %> 

原始答案:

没有人回答这个问题,我努力争取一天自己解决这个问题,所以我将分享我是如何解决它的:

在我看来,我更改了3件事1.添加了一个隐藏字段,将过程id添加到散列中,2。将“comp”对象添加到散列的开头,然后3.将“procedures”更改为“procedures_attributes”(这样生成的哈希看起来就像是form_for fields_for嵌套表单生成的哈希,具有嵌套属性)

所以表格最终看起来像:

 <%= form_tag update_procedures_comp_procedures_path(@comp), :method => :put do %> <% for procedure in @procedures %> <%= fields_for 'comp[procedures_attributes]', procedure do |f| %> <% if params[:field].blank? || params[:field] == "description" %> <%= f.label :description %>
<%= f.text_field :description %> <%= f.hidden_field :id, :value => procedure.id %> <% end %> <% end %> <% end %>

<%= submit_tag "Submit" %>

<% end %>

然后在我的过程控制器中,它不是更新过程对象,而是使用嵌套属性更新comp对象以更新基础过程属性:

 def update_procedures @comp = Comp.find(params[:comp_id]) if @comp.update_attributes(params[:comp]) redirect_to(new_comp_procedure_path(@comp)) else render 'edit_procedures' end 

这似乎有效,但如果有更简单的方法来实现这一点,请让我(以及其他任何读过这篇文章的人)知道。 谢谢。

我知道我已经晚了六年,但看起来这是#update_procedures方法中的一个简单错字:

 # this... @procedures = @comp.procedures.update.(params[:procedures].keys, params[:procedures].values).reject { |p| p.errors.empty? } # should be this... @procedures = @comp.procedures.update(params[:procedures].keys, params[:procedures].values).reject { |p| p.errors.empty? } 

(调用#update后删除了点)

我相信你已经失去了多年的睡眠所以不再哭,你的英雄已经到了。