在erb文件中使用rails form_tag和html表单代码有什么区别?

时间:2014-08-02 08:08:09

标签: html ruby-on-rails ruby

我遇到了我正在制作的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 %>

有谁知道为什么第二段代码不会导致购物车信息被丢弃?

2 个答案:

答案 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