跳转至内容

Ruby on Rails/ActionView/表单

来自 Wikibooks,开放世界中的开放书籍

表单是每个网站的重要组成部分。我们使用它们来联系网站所有者,提供登录凭据或提交数据。Rails 对表单有广泛的支持,并且内置了许多标签来帮助您快速轻松地创建表单。

您可以获得的最基本的表单是用于输入姓名的简单输入字段

<%= form_tag do %>
  <%= label_tag(:my_name, "My name is:") %>
  <%= text_field_tag(:my_name) %>
  <%= submit_tag("Process") %>
<% end %>

这将创建一个非常基本的表单,例如

<form action="/products/test/1" method="post">
 <div style="margin:0;padding:0">
 <input name="authenticity_token" type="hidden" value="KBBEVzSZOkCi/s9LKhYvW/gdwyZzwH2n39py5FggaT4=" />
 </div>

 <label for="my_name">My name is:</label>
 <input id="my_name" name="my_name" type="text" />
 <input name="commit" type="submit" value="Process" />
</form>

这是通过创建一个名为的简单操作实现的test.html.erb在我们的产品视图中,

def test
  #nothing here yet
end

在控制器中添加了一个空操作。页面在浏览器中被调用https://127.0.0.1:3000/products/test/1。因为我们没有更改路由,所以我们必须提供产品的 ID。此外,Rails 创建了一个“authenticity_token”来为我们的表单提供安全功能。您还会注意到我们的输入有一个 ID。Rails 为您提供的每个表单元素提供了 ID 和名称。当然,可以通过提供适当的选项来更改此设置。

以下列表应该让您概述一些表单标签。由于大多数标签的工作方式类似,因此应该很容易弄清楚其中有多少标签的工作原理。此外,请务必查看官方 API

单选框

要创建单选框,只需使用

<%= radio_button_tag :category, "books", true %>

以上将创建

<input id="category_books" name="category" type="radio" value="books" />

如果要更改 ID,可以将自己的 ID 传递给标签(:id => "someid")。要预选一个项目,助手接收的第三个选项应该是一个布尔值。

提交按钮

<%= submit_tag ("Save products", :class => "button") %>

将创建一个提交按钮

<input name="commit" type="submit" class="button" value="Save products" />

文本字段

<%= text_field_tag ('rails') %>

将创建一个空的文本字段

<input id="rails" name="rails" type="text" />

像往常一样,您可以添加 HTML 选项或特定值

<%= text_field_tag ('price', nil, :maxlength => 10) %>

请注意,我们使用“nil”。这是因为我们想要创建一个没有预定义值的文本字段

<input id="price" name="price" type="text" maxlength="10" />

如果我们提供了名称,Rails 将添加 HTML 属性“value”

<input id="price" name="price" type="text" maxlength="10" value="my predefined value instead of nil" />

下拉选择框

表单中的一项常见任务是让用户从下拉选择框(或下拉列表)中选择某些内容。要显示一个简单的下拉选择框,我们可以组合一些方便的方法

<%= select_tag (:name, options_for_select([['Peter','pete'],['Joseph', 'jo']]))%>

将创建

<select id="name" name="name">
 <option value="pete">Peter</option>
 <option value="jo">Joseph</option>
</select>

另一个不错的助手select_*系列是select_year。当您希望用户选择他的出生年份时,您可以使用类似以下内容:

<%= select_year Date.today, :start_year => 2009, :end_year => 1900  %>

这将创建一个包含所有年份的下拉选择框,从 2009 年开始到 1900 年,当前年份(Date.today作为第一个参数)被预选。请务必查看日期的其他助手Datehelpers

处理错误

[编辑 | 编辑源代码]

既然您知道如何在 Rails 中正确显示表单,我们正在寻找一种方法来向用户提供有关其输入的反馈。无论是正确的还是需要重新输入一些值。您已经阅读了有关如何在将表单数据写入数据库之前对其进行验证的信息。现在您将看到如何显示错误。基本上,有两种方法可以让我们显示错误error_messageserror_messages_for。名称很好地说明了这两者之间的区别error_messages显示表单的所有错误,而error_messages_for显示给定模型的错误。

使用这些方法很容易

<% form_for(@product) do |f| %>
  <%= f.error_messages %>
    <p>
    <!-- different form tags -->
    </p>
<% end %>

将显示所有错误消息:默认消息或您在模型中指定的错误消息(:message => "仅允许整数"). error_messages_for以类似的方式使用。然后它显示与给定名称匹配的字段的错误消息(:name在这种情况下)

<%= error_messages_for :name %>

您还可以进一步自定义在框中显示的错误消息

<%= f.error_messages :header_message => "Invalid product!", :message => "Correct your entries", :header_tag => :h6 %>

高级表单

[编辑 | 编辑源代码]

到目前为止,我们主要使用名称末尾带有_tag的表单元素。在使用模型时(例如,您想更新数据或创建新的数据集),您希望使用更适合此工作的表单元素。没有新的元素需要学习,我们只需使用我们已经知道的元素,但不要在末尾添加 _tag(比较form_tagform_for).

假设我们想通过表单创建一个新的产品

我们有一个控制器,它有一个操作……products_controller.rb

#...
def new
  @product= Product.new
end
#...

……和一个视图(view/products/new.html.erb)与我们的@product实例

<% form_for :product, @product, :url=>{:action => "create"} do |f| %>
  <%= f.text_field :name %>
  <%= f.text_field :price %, :size => 10 >
  <%= f.text_field :amount%, :size =>5 >
  <%= submit_tag "New Product" %>
<% end %>

将创建类似于以下内容的 HTML

<form action="/products" class="new_product" id="new_product" method="post">
 <div style="margin:0;padding:0">
 <input name="authenticity_token" type="hidden" value="bgqa1sbwcC5J/tIpPtJjX/3slveFNJg3WZntSOyHT4g=" />
 </div>
 <input id="product_name" name="post[name]" size="30" type="text" />
 <input id="product_price" name="post[price]" size="10" type="text" />
 <input id="product_amount" name="post[amount]" size="5" type="text" />
 <input id="product_submit" name="commit" type="submit" value="Update" />

</form>

让我们检查代码form_for在其侧有一些代码,:product引用我们想要使用的模型的名称,并且@product是对象本身的实例(在本例中,它将是一个新产品)。我们循环或“yield”遍历form_for使用变量f的对象。其余部分使用您已经熟悉的代码。我们使用操作“create”来处理文件的创建。


RESTful 资源

[编辑 | 编辑源代码]

上面显示的方法可能与您在其他 Rails 应用程序中看到的不太一样。它们中的大多数将使用 RESTful 资源。这使 Rails 可以选择如何处理数据。这使得form_for方法更容易理解和阅读

form_for :product, @product, :url=>{:action => "create"}

变成

form_for (@product)

这好多了,不是吗?现在form_for标签看起来相同,无论您是创建新产品还是更新现有产品。Rails 足够智能,可以识别操作并为我们提供正确的 HTML 属性(参见<form action="/products" class="new_product" id="new_product" method="post">)

要了解有关路由和 REST 的更多信息,请务必查看路由。

使用模型创建下拉选择框

[编辑 | 编辑源代码]

我们已经了解了如何使用内置助手创建下拉选择框。但是您可能还想在下拉选择框中显示模型的内容。为了展示如何做到这一点,我们想从数据库中选择类别,以便用户可以选择相应的类别

<%=f.collection_select :category, :id, Category.all, :name, :name.downcase %>

如果您的数据库中有一些类别,则 HTML 可能类似于

<select id="category_id" name="category[id]">
 <option value="cds">CDs</option>
 <option value="books">Books</option>
 <option value="dvds">DVDs</option>
</select>

注意.downcase:如果您的数据库需要以这种方式工作,这将以小写形式写入 HTML 值。这只是您工作的起点。要查看更多示例和说明,一个好的起点是官方 API

华夏公益教科书