将form_tag路由到非Restful操作,而不在浏览器的url中包含操作名称

时间:2017-01-04 09:31:28

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

我在index.html.erb中有一个form_tag,它必须路由到动作update_multiple,以便在表单中选择更新DB。但是有很多问题都与形式和路线相关联。

问题1:尽管在form_tag中明确地将动作和方法作为PUT,但它将_method作为删除并继续销毁动作。我不确定索引表格是否不采取非休息行动。

点击提交后,错误为:

  

{ “UTF8”=> “中✓”, “_方法”=> “中删除”, “authenticity_token”=> “中E / NgCpW + PQ ==”, “真”=>“中{:值=> nil}“,”false“=>”{:value => nil}“,”cv_attachment_id“=>”33“,”commit“=>”选择主要“,”user_id“=> ; “97”, “ID”=> “中update_multiple”}

cv_attachment_id是选择的记录,但是最后一个id是什么,正常操作应该是什么,以及什么是true和false都设置为nil?

index.html.erb中的表单代码

<%= form_tag update_multiple_user_cv_attachments_path, method: :put, action: :update_multiple do %>
      <table class="table table-bordered table-striped">
        <thead>
          <tr>
            <th> Select a CV </th>
            <th> Resume Name </th>
            <th> Creation Date </th>
            <th> Delete Resume </th>
          </tr>
        </thead>
        <tbody>
        <% @cv_attachments.each do |cv_attachment| %>
        <%= hidden_field_tag cv_attachment.main, :value => params[:main] %>
          <tr>
            <td><%= radio_button_tag "cv_attachment_ids[]", cv_attachment.id, cv_attachment.main %> </td>
            <td><%= cv_attachment.attachment.file.basename %></td>
            <td><%= cv_attachment.posting_date %></td>
            <td><%= button_to "Delete", user_cv_attachment_path(current_user, cv_attachment), method: "delete", data: { confirm: 'Are you sure?' }, class: "btn btn-danger btn-outline btn-md" %></td>
          </tr>
        <% end %>
        </tbody>
      </table>
      <br>
      <%= submit_tag "Select Main", :class =>'button' %>
     <% end %>

的routes.rb

#resources :cv_attachments, only: [:index, :show, :edit, :create, :new, :destroy,]

resources :cv_attachments do
  collection do
    put 'update_multiple'
  end
end

问题2:正如你所看到的,我已经为Restful和非restful动作指定了2个cv_attachments,并且因为它搞砸了路线,我不得不评论Restful的那些,以便如何同时使用它们。

问题3:同样通过收集并在点击提交之后将其添加到url的末尾,如:

http://localhost:3000/users/97/cv_attachments/update_multiple

但我不想在网址中添加操作名称:http://localhost:3000/users/97/cv_attachments

2 个答案:

答案 0 :(得分:0)

我倾向于在用户上创建成员路线。

路由

 resources :users do
  member do
    post :update_main_attachment
  end
end

形式

<%= form_tag update_main_attachment_user_path do %>
  <thead></thead>
  <tbody>
    <% @cv_attachments.each do |cv_attachment| %>
      <% if cv_attachment.main %>
        <%= hidden_field_tag "ex_main_cv", cv_attachment.id %>
      <% end %>
      <tr>
        <td><%= radio_button_tag "main_cv", cv_attachment.id, cv_attachment.main %> </td>
        <td><%= cv_attachment.attachment.file.basename %></td>
      </tr>
    <% end %>
  </tbody>
<% end %>

要回答您的第二个问题,您可以在资源丰富的路线下嵌套收集路线:

resources :cv_attachments, only: [:index, :show, :edit, :create, :new, :destroy,] do
  collection do
    put 'update_multiple'
  end
end

对于第3个问题,您可以使用:as选项为收集路由命名。请参阅the Rails docs

答案 1 :(得分:0)

@Margo thx再次因为我接受了你的输入。我弄清楚为什么表单去破坏而不是更新。实际上有一个button_to用于删除附件,一旦我更改为link_to,表单就转到了正确的控制器方法。我从来没有怀疑一个无形的按钮,这不是'形式提交'按钮,是罪魁祸首!

这是解决方案:routes.rb

resources :cv_attachments, only: [:index, :show, :create, :new, :destroy] do
collection do
  put 'update_multiple'
end

index.html - 仅提供表单的一部分

<tbody>
          <% @cv_attachments.each do |cv_attachment| %>
            <% if cv_attachment.main %>
                <%= hidden_field_tag "ex_main", cv_attachment.id %>
            <% end %>
            <tr>
              <td><%= radio_button_tag "new_main", cv_attachment.id, cv_attachment.main, :id => "#{cv_attachment.id}"%> </td>
              <td><%= cv_attachment.attachment.file.basename %></td>
              <td><%= cv_attachment.posting_date %></td>
              <td><%= link_to "Delete", user_cv_attachment_path(current_user, cv_attachment), method: "delete", data: { confirm: 'Are you sure?' }, class: "btn btn-danger btn-outline btn-md" %></td>
            </tr>
          <% end %>
        </tbody>

控制器:

def update_multiple
if request.put?
  if params["ex_main"] != params["new_main"]
    CvAttachment.find(params[:ex_main]).toggle!(:main)
    CvAttachment.find(params[:new_main]).toggle!(:main)
  end
end