Rails form_tag与form_for

Rails form_tag与form_for

Rails中表单是由form_tag和form_for实现的:

form_tag

form_tag 方法是最基本的表单辅助方法。

<%= form_tag do %>
  Form contents
<% end %>

无参数调用 form_tag 方法会创建 标签,在提交表单时会向当前页面发起 POST 请求。例如,假设当前页面是 /home/index,上面的代码会生成下面的 HTML(为了提高可读性,添加了一些换行):

Form contents

我们注意到,上面的 HTML 的第二行是一个 hidden 类型的 input 元素。这个 input 元素很重要,一旦缺少,表单就不能成功提交。这个 input 元素的 name 属性的值是 utf8,用于说明浏览器处理表单时使用的字符编码方式。对于所有表单,不管表单动作是“GET”还是“POST”,都会生成这个 input 元素。

上面的 HTML 的第三行也是一个 input 元素,元素的 name 属性的值是 authenticity_token。这个 input 元素是 Rails 的一个名为跨站请求伪造保护的安全特性。在启用跨站请求伪造保护的情况下,表单辅助方法会为所有非 GET 表单生成这个 input 元素。

form_for

如果 Person 模型有很多属性需要修改,那么实例变量对象的名称就需要重复写很多遍。更好的解决方案是把表单绑定到模型对象上,为此我们可以使用 form_for 辅助方法。

假设有一个用于处理文章的控制器 app/controllers/articles_controller.rb:

def new
  @article = Article.new
end

在对应的 app/views/articles/new.html.erb 视图中,可以像下面这样使用 form_for 辅助方法:

<%= form_for @article, url: {action: "create"}, html: {class: "nifty_form"} do |f| %>
  <%= f.text_field :title %>
  <%= f.text_area :body, size: "60x12" %>
  <%= f.submit "Create" %>
<% end %>

这里有几点需要注意:
实际需要修改的对象是 @article。
form_for 辅助方法的选项是一个散列,其中 :url 键对应的值是路由选项,:html 键对应的值是 HTML 选项,这两个选项本身也是散列。还可以提供 :namespace 选项来确保表单元素具有唯一的 ID 属性,自动生成的 ID 会以 :namespace 选项的值和下划线作为前缀。
form_for 辅助方法会产出一个表单生成器对象,即变量 f。
用于生成表单控件的辅助方法都在表单生成器对象 f 上调用。
上面的代码会生成下面的 HTML:

form_for 辅助方法的第一个参数决定了 params 使用哪个键来访问表单数据。在上面的例子中,这个参数为 @article,因此所有 input 控件的 name 属性都是 article[attribute_name] 这种形式,而在 create 动作中 params[:article] 是一个拥有 :title 和 :body 键的散列。

总结:在表单生成器上调用的辅助方法和模型对象辅助方法几乎完全相同,区别在于前者无需指定需要修改的对象,因为表单生成器已经指定了需要修改的对象。

表单控件

表单控件包括文本区域、密码框、隐藏输入字段、搜索字段、电话号码字段、日期字段、时间字段、颜色字段、本地日期时间字段、月份字段、星期字段、URL 地址字段、电子邮件地址字段、数字字段和范围字段:

<%= text_area_tag(:message, "Hi, nice site", size: "24x6") %>
<%= password_field_tag(:password) %>
<%= hidden_field_tag(:parent_id, "5") %>
<%= search_field(:user, :name) %>
<%= telephone_field(:user, :phone) %>
<%= date_field(:user, :born_on) %>
<%= datetime_local_field(:user, :graduation_day) %>
<%= month_field(:user, :birthday_month) %>
<%= week_field(:user, :birthday_week) %>
<%= url_field(:user, :homepage) %>
<%= email_field(:user, :address) %>
<%= color_field(:user, :favorite_color) %>
<%= time_field(:task, :started_at) %>
<%= number_field(:product, :price, in: 1.0..20.0, step: 0.5) %>
<%= range_field(:product, :discount, in: 1..100) %>

你可能感兴趣的:(Rails)