我遇到了我正在制作的rails应用程序的问题。它是一个电子商务网站,在用户输入其结算信息的页面上,发布导致购物车信息丢失的表单。
我通过更改erb文件中的标记解决了这个问题。表单的第一个代码是:
<form method="post" id="checkout" action="<%= url_for :action => :place_order %>" >
<%= submit_tag "Place Order" %>
</form>
这没有用,所以我尝试了以下方法:
<% form_tag :method => 'post', :controller => 'checkout', :action => 'place_order' do %>
<%= submit_tag 'Place Order 2' %>
<% end %>
有谁知道为什么第二段代码不会导致购物车信息被丢弃?
答案 0 :(得分:2)
我打算把它写成评论,但它太长了
<强>助手强>
通常,您通常需要尽可能使用Rails助手(其中form_tag
是一个)。
原因是随着Rails(&amp; HTML)的发展,你会发现帮助者会适应以跟上当前的语法,而使用“裸”的HTML却不会。这不仅保留了您的应用conventional,还保留了DRY
通过手动输入HTML表单,您不仅可以解决语法更改问题,还可以获得Rails集成提供的任何好处,例如CSRF
保护
<强>的form_tag 强>
关于form_tag
您已使用form_tag
&amp;来定义:controller
的路线:action
。使用将在您的Rails route_helpers
文件中定义的routes
之一,您会好得多:
#config/routes.rb
resources :checkout, path_names: { create: "place_order" }
这将允许您使用以下内容:
<%= form_tag checkout_place_order_path do %>
还必须注意,默认情况下form_for
标记实际上会使用:post
方法
-
<强> PARAMS 强>
您提到您的商品的params
未使用您的标准表单传递。
实际上这很简单 - Rails builds a params
hash每当您通过HTML表单向控制器发送数据时。
您遇到的问题是,如果您使用“裸”HTML定义表单,那么这些参数将无法正确生成(它们是根据您的表单元素名称构建的)。这意味着如果您想将正确的数据发送到您的应用程序,您将更适合使用其中一个帮助程序,例如form_for
(这是您现在发现的)
<强>的form_for 强>
如DMKE
所述,您可能希望使用form_for
。这与form_tag
不同,因为它依赖于使用ActiveRecord
对象。你必须这样做:
#app/controllers/checkout_controller.rb
Class CheckoutController < ApplicationController
def new
@checkout = Checkout.new
end
def create
@checkout = Checkout.new(checkout_params)
@checkout.save
end
end
然后,您可以使用以下内容填充form_for
:
#app/views/checkout/new.html.erb
<%= form_for @checkout do |f| %>
答案 1 :(得分:1)
Rails通常会将隐藏字段形式的CSRF保护令牌添加到HTML表单中,但前提是您使用Rails帮助程序方法。比较这个观点
<% form_tag method: 'post', controller: 'checkout', action: 'place_order' do %>
<%= submit_tag 'Place Order 2' %>
<% end %>
使用此渲染输出:
<form accept-charset="UTF-8" action="/checkout/place_order" method="post">
<div style="display:none">
<input name="utf8" type="hidden" value="✓">
<input name="authenticity_token" type="hidden" value="q5PYT8i+XTlnoKeVqCoz8VMtKKSJP+CXQb/E+G0Vxlk=">
</div>
<input type="submit" name="submit" value="Place Order 2">
</form>
现在,要启动并运行您的原始表单,您可以将此代码段插入<form>
代码:
<%= hidden_field request_forgery_protection_token, value: form_authenticity_token %>
或者您可以禁用CSRF保护(完全不推荐!):
# in your app/controllers/application_controller.rb
skip_before_action :verify_authenticity_token
你至少应该阅读Rails Security Guide关于为什么禁用CSRF保护是一件坏事。
N.B。您有没有理由不使用form_for
?