<commit_before># [Form Helpers][fh]

表单（Form）是给使用者输入的界面，web 应用里面最基础的元素之一。表单写起来很繁琐，Rails 提供很多有用的 helper 让你快速制造出符合不同需求的表单。

## 目录

- [1. 简单的表单](#1-简单的表单)
  - [1.1 通用搜索表单](#11-通用搜索表单)
    - [1.2 Form Helper 调用里传多个 Hash](#12-form-helper-调用里传多个-hash)
    - [1.3 生成表单的 Helpers](#13-生成表单的-helpers)
      - [1.3.1 Checkbox](#131-checkbox)
      - [1.3.2 Radio Buttons](#132-radio-buttons)
    - [1.4 其它相关的 helpers](#14-其它相关的-helpers)
- [2. 处理 Model 对象的 Helpers](#2-处理-model-对象的-helpers)
  - [2.1 Model 对象的 Helpers](#21-model-对象的-helpers)
  - [2.2 将表单绑定至对象](#22-将表单绑定至对象)
  - [2.3 Record Identification](#23-record-identification)
    - [2.3.1 处理 namespace](#231-处理-namespace)
  - [2.4 PATCH、PUT、DELETE 表单是怎么工作的？](#24-patch、put、delete-表单是怎么工作的？)
- [3. 轻松制作下拉式选单](#3-轻松制作下拉式选单)
  - [3.1 Select 与 Option 标签](#31-select-与-option-标签)
  - [3.2 处理 Models 的下拉选单](#32-处理-models-的下拉选单)
  - [3.3 从任意对象集合来的 option 标签](#33-从任意对象集合来的-option-标签)
  - [3.4 Time Zone 与 Country](#34-time-zone-与-country)
- [4. 使用日期与时间的 Form Helpers](#4-使用日期与时间的-form-helpers)
    - [Barebones Helpers](#barebones-helpers)
    - [Model 对象的 Helpers](#model-对象的-helpers)
    - [4.3 常见选项](#43-常见选项)
    - [4.4 单一选项](#44-单一选项)
- [5. 上传文件](#5-上传文件)
    - [5.1 究竟上传了什么](#51-究竟上传了什么)
    - [5.2 处理 Ajax](#52-处理-ajax)
- [6. 客制化 Form Builders](#6-客制化-form-builders)
- [7. 了解参数的命名规范](#7-了解参数的命名规范)
  - [7.1 基本结构](#71-基本结构)
  - [7.2 结合起来](#72-结合起来)
  - [7.3 使用 Form Helpers](#73-使用-form-helpers)
- [8. 给外部的 resource 使用的表单](#8-给外部的-resource-使用的表单)
- [9. 打造复杂的表单](#9-打造复杂的表单)
  - [9.1 设​​定 Model](#91-设​​定-model)
  - [9.2 制作表单](#92-制作表单)
  - [9.3 控制器层面](#93-控制器层面)
    - [9.4 移除对象](#94-移除对象)
    - [9.5 避免有空的 Record](#95-避免有空的-record)
    - [9.6 动态加入 Fields](#96-动态加入-fields)
- [表单相关的 RubyGems](#表单相关的-rubygems)
- [延伸阅读](#延伸阅读)

# 1. 简单的表单

最基本的表单 helper：`form_tag`

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

按下表单送出时，会对页面做 POST。假设上面这个表单在 `/home/index`，生成的 HTML 如下：

```html
<form accept-charset="UTF-8" action="/home/index" method="post">
  <div style="margin:0;padding:0">
    <input name="utf8" type="hidden" value="&#x2713;" />
    <input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" />
  </div>
  Form contents
</form>
```

注意到 HTML 里有个额外的 `div` 元素，里面有两个 `input`。第一个 `input` 让浏览器使用 `UTF-8`。第二个 `input` 是 Rails 内建用来防止 __CSRF (cross-site request forgery protection)__ 攻击的安全机制，每个非 GET 的表单，Rails 都会帮你生成一个这样的 `authenticity_token`。

## 1.1 通用搜索表单

最简单的表单就是搜索表单了，通常有：

* 一个有 GET 动词的表单。
* 可输入文字的 `input`。
* `input` 有 `label`。
* 送出元素

```erb
<%= form_tag("/search", method: "get") do %>
  <%= label_tag(:q, "Search for:") %>
  <%= text_field_tag​​(:q) %>
  <%= submit_tag("Search") %>
<% end %>
```

用到这四个 helper：`form_tag`、`label_tag`、`text_field_tag​​`、`submit_tag`。

会生成如下 HTML：

```html
<form accept-charset="UTF-8" action="/search" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type= "hidden" value="&#x2713;" /></div>
  <label f​​or="q">Search for:</label>
  <input id="q" name="q" type="text" />
  <input name="commit" type="submit" value="Search" />
</form>
```

ID 是根据表单名称（上例为 `q`）所生成，可供 CSS 或 JavaScript 使用。

__切记：搜索表单用正确的 HTTP 动词：GET。__

### 1.2 Form Helper 调用里传多个 Hash

`form_tag` 接受 2 个参数： __动作发生的路径（path）与选项（以 hash 形式传入）__。可指定送出时要用的方法，及更改表单元素的 class 等。
<commit_msg>:raising_hand: Update guides/edge-translation/form-helpers-zh_CN.md @ 2013-11-07 00:44:14 (Taipei Time)<commit_after># [Form Helpers][fh]

表单（Form）是给使用者输入的界面，web 应用里面最基础的元素之一。表单写起来很繁琐，Rails 提供很多有用的 helper 让你快速制造出符合不同需求的表单。

## 目录

- [1. 简单的表单](#1-简单的表单)
  - [1.1 通用搜索表单](#11-通用搜索表单)
    - [1.2 Form Helper 调用里传多个 Hash](#12-form-helper-调用里传多个-hash)
    - [1.3 生成表单的 Helpers](#13-生成表单的-helpers)
      - [1.3.1 Checkbox](#131-checkbox)
      - [1.3.2 Radio Buttons](#132-radio-buttons)
    - [1.4 其它相关的 helpers](#14-其它相关的-helpers)
- [2. 处理 Model 对象的 Helpers](#2-处理-model-对象的-helpers)
  - [2.1 Model 对象的 Helpers](#21-model-对象的-helpers)
  - [2.2 将表单绑定至对象](#22-将表单绑定至对象)
  - [2.3 Record Identification](#23-record-identification)
    - [2.3.1 处理 namespace](#231-处理-namespace)
  - [2.4 PATCH、PUT、DELETE 表单是怎么工作的？](#24-patch、put、delete-表单是怎么工作的？)
- [3. 轻松制作下拉式选单](#3-轻松制作下拉式选单)
  - [3.1 Select 与 Option 标签](#31-select-与-option-标签)
  - [3.2 处理 Models 的下拉选单](#32-处理-models-的下拉选单)
  - [3.3 从任意对象集合来的 option 标签](#33-从任意对象集合来的-option-标签)
  - [3.4 Time Zone 与 Country](#34-time-zone-与-country)
- [4. 使用日期与时间的 Form Helpers](#4-使用日期与时间的-form-helpers)
    - [Barebones Helpers](#barebones-helpers)
    - [Model 对象的 Helpers](#model-对象的-helpers)
    - [4.3 常见选项](#43-常见选项)
    - [4.4 单一选项](#44-单一选项)
- [5. 上传文件](#5-上传文件)
    - [5.1 究竟上传了什么](#51-究竟上传了什么)
    - [5.2 处理 Ajax](#52-处理-ajax)
- [6. 客制化 Form Builders](#6-客制化-form-builders)
- [7. 了解参数的命名规范](#7-了解参数的命名规范)
  - [7.1 基本结构](#71-基本结构)
  - [7.2 结合起来](#72-结合起来)
  - [7.3 使用 Form Helpers](#73-使用-form-helpers)
- [8. 给外部的 resource 使用的表单](#8-给外部的-resource-使用的表单)
- [9. 打造复杂的表单](#9-打造复杂的表单)
  - [9.1 设​​定 Model](#91-设​​定-model)
  - [9.2 制作表单](#92-制作表单)
  - [9.3 控制器层面](#93-控制器层面)
    - [9.4 移除对象](#94-移除对象)
    - [9.5 避免有空的 Record](#95-避免有空的-record)
    - [9.6 动态加入 Fields](#96-动态加入-fields)
- [表单相关的 RubyGems](#表单相关的-rubygems)
- [延伸阅读](#延伸阅读)

# 1. 简单的表单

最基本的表单 helper：`form_tag`

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

按下表单送出时，会对页面做 POST。假设上面这个表单在 `/home/index`，生成的 HTML 如下：

```html
<form accept-charset="UTF-8" action="/home/index" method="post">
  <div style="margin:0;padding:0">
    <input name="utf8" type="hidden" value="&#x2713;" />
    <input name="authenticity_token" type="hidden" value="<PASSWORD>" />
  </div>
  Form contents
</form>
```

注意到 HTML 里有个额外的 `div` 元素，里面有两个 `input`。第一个 `input` 让浏览器使用 `UTF-8`。第二个 `input` 是 Rails 内建用来防止 __CSRF (cross-site request forgery protection)__ 攻击的安全机制，每个非 GET 的表单，Rails 都会帮你生成一个这样的 `authenticity_token`。

## 1.1 通用搜索表单

最简单的表单就是搜索表单了，通常有：

* 一个有 GET 动词的表单。
* 可输入文字的 `input`。
* `input` 有 `label`。
* 送出元素

```erb
<%= form_tag("/search", method: "get") do %>
  <%= label_tag(:q, "Search for:") %>
  <%= text_field_tag​​(:q) %>
  <%= submit_tag("Search") %>
<% end %>
```

用到这四个 Helper：`form_tag`、`label_tag`、`text_field_tag​​`、`submit_tag`。

会生成如下 HTML：

```html
<form accept-charset="UTF-8" action="/search" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type= "hidden" value="&#x2713;" /></div>
  <label f​​or="q">Search for:</label>
  <input id="q" name="q" type="text" />
  <input name="commit" type="submit" value="Search" />
</form>
```

ID 是根据表单名称（上例为 `q`）所生成，可供 CSS 或 JavaScript 使用。

__切记：搜索表单用正确的 HTTP 动词：GET。__

### 1.2 Form Helper 调用里传多个 Hash

`form_tag` 接受 2 个参数： __动作发生的路径（path）与选项（以 hash 形式传入）__。可指定送出时要用的方法，及更改表单元素的 class 等。

{'fraction_non_alphanumeric': 0.21188978736148548, 'fraction_numerical': 0.05345911949685535, 'mean_word_length': 4.044561933534744, 'pattern_counts': {'":': 0, '<': 48, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3861292', 'n_tokens_mistral': 4021, 'n_tokens_neox': 4038, 'n_words': 522}