基礎Ruby on Rails Chapter6 フォームとモデル

前 [基礎Ruby on Rails Chapter5 7つのアクション](https://qiita.com/tseno/items/4c107bf53ca80613ffea)
次 [基礎Ruby on Rails Chapter6 レコードの作成、更新、削除](https://qiita.com/tseno/items/5b3f7ea85e38b115ae30)

# フォームとモデル

## モデルとフォームの連携

- `params[:member]`でmemberのハッシュが全部取り出せるので、モデルに丸ごとセットすれば全部保存できる。

```rb
# 属性全部セット
@member.assign_attribute(params[:member])
# レコードを保存
@member.save
```

## フォームの記述

### newアクションとeditアクション

```rb:app/controllers/member_controller.rb（一部）
  def new
    @member = Member.new(birthday: Date.new(1980,1,1))
  end
  
  def edit
    @member = Member.find(params[:id])
  end
```

### 新規作成フォーム

- ブロックパラメータのformには、ActionView::Helpers::FormBuilderクラスのオブジェクト（フォームビルダー）が渡される。

```erb:app/views/members/new.html.erb
<%= form_for @member do |form| %>
<% end %>
```

- action="/members"、method="post"で、newアクション。
- 空のフォームには、hiddenが2つ作成される。
  - utf8は、古いIEにパラメータをUTF-8で送信されるダミーパラメータ
  - authenticity_tokenは、CSRF対策のため。

```html
<form class="new_member" id="new_member" action="/members" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="&#x2713;" />
<input type="hidden" name="authenticity_token" value="OxJX61itSGGfaM+LhUvLwANWfJMRxxqz7GDMWxqVBjGZ/hCcvvmWpHtKOC4dBpfXUoOhfNa080fc83gnvZElkw==" />
</form>
```

### 更新フォーム

```erb:app/views/members/edit.html.erb
<%= form_for @member do |form| %>
<% end %>
```

- action="/members/1"、method="patch"で、updateアクション。
- 空のフォームには、hiddenが3つ作成される。
  - utf8は、古いIEにパラメータをUTF-8で送信されるダミーパラメータ
  - _methodは、古いIEにパラメータをUTF-8で送信されるダミーパラメータ
  - authenticity_tokenは、CSRF対策のため。

```html
<form class="edit_member" id="edit_member_1" action="/members/1" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="&#x2713;" />
<input type="hidden" name="_method" value="patch" />
<input type="hidden" name="authenticity_token" value="eV4EdgoePjwA0s9SWTbf/Q/JOUAzRudvzlUAGkHYJ4Poxe9I8nTovU6tQfOVciiKNJTV22n+n5H7m//X8vP/4Q==" />
</form>
```

## フォーム部品の記述

- newとeditのフォームを共通化した部品、_form.html.erbを作成する。

```erb:app/views/_form.html.erb
<table class="attr">
  <tr>
    <th><%= form.label :number, "背番号" %></th>
    <td><%= form.text_field :number, size: 8 %></td>
  </tr>
  <tr>
    <th><%= form.label :name, "ユーザー名" %></th>
    <td><%= form.text_field :name %></td>
  </tr>
  <tr>
    <th><%= form.label :full_name, "氏名" %></th>
    <td><%= form.text_field :full_name %></td>
  </tr>
  <tr>
    <th>性別</th>
    <td>
      <%= form.radio_button :sex, 1 %>
      <%= form.label :sex_1, "男" %>
      <%= form.radio_button :sex, 2 %>
      <%= form.label :sex_2, "女" %>
    </td>
  </tr>
  <tr>
    <th>
      <%= form.label :birthday, "誕生日", for: "member_birthday_li" %>
    </th>
    <td>
      <%= form.date_select :birthday, start_year: 1940, end_year: Time.current.year, use_month_numbers: true %>
    </td>
  </tr>
  <tr>
    <th><%= form.label :email, "メールアドレス" %></th>
    <td><%= form.text_field :email %></td>
  </tr>
  <tr>
    <th>管理者</th>
    <td>
      <%= form.check_box :administrator %>
      <%= form.label :administrator, "管理者" %>
    </td>
  </tr>
</table>
```

- 新規登録フォームの書き換え

```erb:app/views/members/new.html.erb
<% @page_title = "会員の新規登録" %>

<h1><%= @page_title %></h1>

<%= form_for @member do |form| %>
  <%= render "form", form: form %>
  <div><%= form.submit %></div>
<% end %>
```

- 更新フォームの書き換え

```erb:app/views/members/edit.html.erb
<% @page_title = "会員情報の編集" %>

<h1><%= @page_title %></h1>

<div class="toolbar"><%= link_to "会員の詳細に戻る", @member %></div>

<%= form_for @member do |form| %>
  <%= render "form", form: form %>
  <div><%= form.submit %></div>
<% end %>

```

- newアクションのページ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/88686/2085352f-6cfd-1a95-d630-37f574977dc7.png)

- editアクションのページ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/88686/ef5cb783-6769-9d2a-1fe1-fb4f31bbfe2e.png)

## フォームビルダーのメソッド

### １行テキスト、パスワード、隠し項目

- text_fieldメソッドは、1行のテキストに使う。
- password_fieldメソッドを使うと、パスワード入力欄になる。
- hidden_fieldメソッドを使うと、表示されない(hidden)欄になる。

```erb
名前：<%= form.text_field :name, size: 16 %><br />
パスワード：<%= form.password_field :password, size: 12 %>
<%= form.hidden_field :id %>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/88686/968c3a41-9723-fba4-577d-baffccd7c142.png)

### 複数行テキスト

- text_areaメソッドは、複数行のテキストに使う。cols、rowsはオプションで指定する。

```erb
備考：<br />
<%= form.text_area :name, cols: 40, rows: 3 %>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/88686/b208fabc-f0d0-af08-eb19-d923ec3eed1e.png)

### チェックボックス

- check_boxメソッドは、チェックボックスに使う。第2引数にはHTMLの属性をハッシュで指定できる。
- 第3引数と第4引数にオンの場合とオフの場合の値を並べる。デフォルトでは、on=1、off=0。モデルでは、1=true、0=false。
- 最初からチェックオンにしておきたいときは、@member.administrator = trueのように、コントローラでモデルオブジェクトに値を入れておく。

```erb
<%= form.check_box :administrator, {}, "on", "off" %>管理者
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/88686/e50253a2-e8f4-46d5-e2cf-30935bf82fd5.png)

### ラジオボタン

- radio_buttonメソッドは、ラジオボタンに使う。第2引数にはラジオボタンの値（value）を指定できる。
- 最初からチェックが付いた状態にしたいときは、@member.sex = 2のように、コントローラでモデルオブジェクトに値を入れておく。

```erb
<%= form.check_box :administrator, {}, "on", "off" %>管理者
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/88686/4a64f078-f3f4-7475-c9a5-eb89a4b4c084.png)

### 選択リスト

- selectメソッドは、プルダウンによる選択リストに使う。第2引数には選択肢を配列で指定できる。
- 最初から選択された状態にしたいときは、@member.area = "東町"や、@member.area = 3のように、コントローラでモデルオブジェクトに値を入れておく。

```erb
<% options = ["本町", "東町", "南町", "北町", "その他"] %>
地域：<%= form.select :area, options %>
```

- value属性の値を指定したいときは、配列の配列で文字列と値を並べる。

```erb
<% options = [["本町",1], ["東町",2], ["南町",3], ["北町",4], ["その他",5]] %>
地域：<%= form.select :area, options %>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/88686/51103451-50d1-cf0a-b859-8dd35935e807.png)

### 日付と時間の選択

- date_selectメソッドは、日付の選択に使う。
- datetime_selectメソッドは、日付と時間の選択に使う。
- オプションとして、最初の年（start_year）、最後の年（end_year）、月の表示を数字にするか（use_month_numbers）を指定できる。

```erb
誕生日：<%= form.date_select :birthday, start_year: 1940, end_year: Time.current.year, use_month_numbers: true %>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/88686/42276694-27d5-ddc8-d63c-4cab5ad4485e.png)

### ファイルのアップロード

- file_fieldメソッドは、ファイルのアップロードに使う。

```erb
画像：<%= form.file_field :upload_file %>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/88686/11ebf542-e3eb-5619-43c0-ffb9dcd3829c.png)

### 送信ボタン

- submitメソッドは、フォームの送信ボタンに使う。引数にボタン名を指定できる。

```erb
<%= form.submit "更新" %>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/88686/71232147-ad5f-fee7-0b84-c4ad77b7a04a.png)

### ラベル

- labelメソッドは、入力欄に対応するラベルに使う。引数には対応する入力欄の属性名を指定できる。第2引数には、ラベルのテキストを指定できる。

```erb
<%= form.label :name, "名前" %><%= form.text_field :name, size: 16 %>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/88686/13986e9e-ed03-2f83-79cc-a595e21fa7e3.png)

参考
[改訂4版 基礎 Ruby on Rails (IMPRESS KISO SERIES)](https://www.amazon.co.jp/%E6%94%B9%E8%A8%824%E7%89%88-Ruby-Rails-IMPRESS-KISO/dp/429500460X/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=1536666358&sr=1-1)