Rails form_tag 路由到非 Restful 动作,不包含浏览器 url 中的动作名称
Rails form_tag routing to non-Restful action without including name of action in url on the browser
我在 index.html.erb
中有一个 form_tag,它必须路由到一个操作 update_multiple 以使用表单中的选择更新数据库。但是有多个问题都与形式和路线相互关联。
问题 1:尽管在 form_tag 中明确给出了操作和方法作为 PUT,但它采用 _method 作为删除并继续销毁操作。我不确定索引表是否不采取非 restful 操作。
点击提交后的错误是:
{"utf8"=>"✓","_method"=>"delete","authenticity_token"=>"e/NgCpW+PQ==","true"=>"{:value=>nil}","false"=>"{:value=>nil}","cv_attachment_id"=>"33","commit"=>"Select Main","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:同样通过收集并在点击提交后将 update_multiple 添加到 url 的末尾,例如:
http://localhost:3000/users/97/cv_attachments/update_multiple
但我不想要 url 中的操作名称:http://localhost:3000/users/97/cv_attachments
我倾向于在用户上创建一个成员路由。
路线
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 %>
为了回答你的第二个问题,你可以在 resourceful routes 下嵌套 collection routes:
resources :cv_attachments, only: [:index, :show, :edit, :create, :new, :destroy,] do
collection do
put 'update_multiple'
end
end
对于第 3 期,您可以使用 :as
选项为收集路线命名。参考the Rails docs.
@Margo 再次感谢,因为我已经接受了你的意见。我弄清楚了为什么表单会销毁而不是更新。实际上有一个 button_to 用于删除附件,当我更改为 link_to 时,表单就转到了正确的控制器 method.And 我从来没有怀疑过一个看起来无害的按钮,它不是 'form Submit'-按钮,是罪魁祸首!
解决方法如下: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
我在 index.html.erb
中有一个 form_tag,它必须路由到一个操作 update_multiple 以使用表单中的选择更新数据库。但是有多个问题都与形式和路线相互关联。
问题 1:尽管在 form_tag 中明确给出了操作和方法作为 PUT,但它采用 _method 作为删除并继续销毁操作。我不确定索引表是否不采取非 restful 操作。
点击提交后的错误是:
{"utf8"=>"✓","_method"=>"delete","authenticity_token"=>"e/NgCpW+PQ==","true"=>"{:value=>nil}","false"=>"{:value=>nil}","cv_attachment_id"=>"33","commit"=>"Select Main","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:同样通过收集并在点击提交后将 update_multiple 添加到 url 的末尾,例如:
http://localhost:3000/users/97/cv_attachments/update_multiple
但我不想要 url 中的操作名称:http://localhost:3000/users/97/cv_attachments
我倾向于在用户上创建一个成员路由。
路线
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 %>
为了回答你的第二个问题,你可以在 resourceful routes 下嵌套 collection routes:
resources :cv_attachments, only: [:index, :show, :edit, :create, :new, :destroy,] do
collection do
put 'update_multiple'
end
end
对于第 3 期,您可以使用 :as
选项为收集路线命名。参考the Rails docs.
@Margo 再次感谢,因为我已经接受了你的意见。我弄清楚了为什么表单会销毁而不是更新。实际上有一个 button_to 用于删除附件,当我更改为 link_to 时,表单就转到了正确的控制器 method.And 我从来没有怀疑过一个看起来无害的按钮,它不是 'form Submit'-按钮,是罪魁祸首!
解决方法如下: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