【问题标题】:Editing nested collection through 1 form in Rails在 Rails 中通过 1 个表单编辑嵌套集合
【发布时间】:2012-11-06 05:53:14
【问题描述】:

我正在尝试创建一个表单,我可以在其中在单个视图中单独编辑集合中的所有项目。我使用 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

在我看来:

<%= form_tag update_procedures_comp_procedures_path(@comp), :method => :put do %>
    <% for procedure in @procedures %>
        <%= fields_for "procedures[]", procedure do |f| %>
            <% if params[:field].blank? || params[:field] == "description" %>
            <%= f.label :description %>
                <%= f.text_field :description %>
        <% end %>
        <% end %>
    <% end %>   
    <p><%= submit_tag "Submit" %></p>
<% end %>

我还尝试将“edit_procedures”方法从 GET 更改为 POST,但随后出现此错误:未知操作,无法为 ProceduresController 找到“显示”操作。

感谢您的帮助。

【问题讨论】:

    标签: ruby-on-rails forms ruby-on-rails-3.2


    【解决方案1】:

    更新:

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

    <%= 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”(这样生成的hash就和form_for fields_for嵌套属性的嵌套表单生成的hash一模一样)

    所以表格最终看起来像:

    <%= 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 %><br />
                <%= f.text_field :description %>
                <%= f.hidden_field :id, :value => procedure.id %>
                <% end %>
        <% end %>
         <% end %>  
    <p><%= submit_tag "Submit" %></p>
    <% 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 
    

    这似乎可行,但如果有更直接的方法来完成此操作,请告诉我(以及阅读此内容的任何其他人)。谢谢。

    【讨论】:

      【解决方案2】:

      我知道我迟到了六年,但看起来这是您的 #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后删除了点)

      我相信你已经为此失眠了年,所以不要再哭了,你的英雄已经到来了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-02
        • 2015-10-07
        • 1970-01-01
        • 1970-01-01
        • 2014-02-20
        相关资源
        最近更新 更多