Rails 7中创建Log表单跳转DELETE路由而非POST路由问题
问题原因
问题出在HTML表单嵌套上。从你提供的渲染后HTML可以看到,Log的表单内部嵌套了Like的删除表单(包含<input type="hidden" name="_method" value="delete">字段)。HTML规范不支持表单嵌套,浏览器解析时会把内部表单的字段合并到外层表单中,导致Rails将原本的POST请求识别为DELETE请求(Rails通过_method字段判断请求方法)。
具体来说,FilmCoverComponent组件里渲染了点赞相关内容,其中包含一个删除Like的表单(带_method=delete的隐藏输入),而这个组件被放在了Log表单的<div class="mr-4 hidden sm:block">内部,形成了非法的表单嵌套结构。当你点击Log表单的“Save”按钮时,外层表单会包含这个_method=delete字段,Rails就会把请求路由到DELETE /logs。
解决方案
- 调整组件渲染位置:把
FilmCoverComponent移到Log表单的外部,确保两个表单完全独立,没有嵌套关系。修改logs/_form.html.erb:
<%= render "shared/modal" do %> <div class="flex"> <div class="mr-4 hidden sm:block"> <%= render FilmCoverComponent.new(film, size: :lg, link: false) %> </div> <%= form_with(model: log) do |form| %> <div class="flex-1 flex flex-col justify-between space-y-2"> <div class="text-display text-xl"><%= film.name %></div> <%= form.hidden_field :film_id, value: film.id %> <div class="flex"> <%= form.submit "Save", class: "btn-base btn-primary btn-md btn-block" %> </div> </div> <% end %> </div> <% end %>
- 检查Like组件的实现:确保Like的表单是独立的,没有被意外嵌套到其他表单中。如果使用Turbo,可以考虑用
turbo_frame_tag或者turbo_stream处理点赞/取消点赞操作,避免直接在其他表单内部渲染表单元素。
内容的提问来源于stack exchange,提问作者amoks
相关产品推荐
相关产品推荐

