gpt4 book ai didi

ruby-on-rails - form_with 没有命中 Controller 的 Action

转载 作者:行者123 更新时间:2023-12-04 17:44:44 24 4
gpt4 key购买 nike

我尝试了 form_tagform_with - 结果是一样的, Controller 的 Action 永远不会被触发。

# routes.rb
resources :products do
member do
patch :add_comment
end
end

# products_controller.rb
def add_comment
# !!! damn form_with never gets here!!!
product.add_comment!(params[:comment_id])
redirect_back(fallback_location: products_path)
end

# view
<%= form_with(url: add_comment_product_path, local: true) do |form| %>
<%= form.text_field :comment_id %>
<%= form.submit 'Add comment' %>
<% end %>

实际日志:

Started PATCH "/products/1"
Processing by ProductsController#update as HTML
Parameters: {
"utf8"=>"✓",
"authenticity_token"=>"token",
"products"=>{a_lot: :of_stuff},
"comment_id"=>"2",
"commit"=>"Add comment",
"id"=>"1"
}

预期日志:

Started PATCH "/products/1/add_comment?comment_id=2"
Processing by ProductsController#add_comment as HTML
Parameters: {
"utf8"=>"✓",
"authenticity_token"=>"token",
"comment_id"=>"2",
"id"=>"1"
}

编辑:

我认为这与此 form_with 嵌套在更大的表单中有关,当我点击 Add comment 时它看起来会触发外部提交

最佳答案

Rails 处理此问题的方法是将其作为单独但嵌套的资源 - 因为您实际上是在创建新资源(评论)而不是修改产品本身。

这也使您的代码符合单一职责原则 (SRP),因为每个 Controller 仅处理单一类型资源的 CRUD。

您可以 nest resources通过嵌套对 resources 的调用:

resources :products do
resources :comments, shallow: true
end

然后设置 CommentsController 来处理 CRUD 评论:

class CommentsController < ApplicationController
before_action :set_comment, only: [:index, :new, :create]

# GET /products/:product_id/comments
def index
@comments = @product.comments
end

# GET /products/:product_id/comments/new
def new
@comment = @product.comments.new
end

# POST /products/:product_id/comments
def create
@comment = @product.comments.new(comment_params)
if @comment.save
redirect_to @product, success: 'Comment created'
else
render :new
end
end

# ...

private
def set_product
@product = Product.find(params[:product_id])
end

def comment_params
params.require(:comment)
.permit(:foo, :bar)
end
end

要将表单操作属性设置为指向嵌套路由,您只需使用数组或命名的 product_comments(product_id: @product.to_param) 路由助手。

<%= form_with(model: @comment, url: [@comment.product, @comment], local: true) do |form| %>
<%= form.submit 'Add comment' %>
<% end %>

由于产品 ID 通过 URI 传递,因此无需通过隐藏输入传递它。

I think it has something to do with the fact that this form_with is nested into bigger form and it looks when I hit Add comment it triggers the outer submit

您应该注意 HTML 标准(包括 HTML5 和更早的 (x)HTML 标准)不允许嵌套表单元素,并且如果浏览器应使用嵌套表单的 action 属性,则行为可能非常不可预测,因为它没有指定或将事件冒泡到您的情况下最有可能发生的父表单元素。参见:http://w3.org/TR/html5/forms.html

关于ruby-on-rails - form_with 没有命中 Controller 的 Action ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52669061/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com