【初心者向け】フォームヘルパーの使い方

#1.フォームを用いた送信の仕方

##1-a. 下準備①新しいアプリを用意する

```
 $ cd desktop　
 $ rails new formapp
```

既存のアプリの中に、フォームを作る場合はアプリを新しく作る必要はありません。その際は、しっかり既存アプリのフォルダに移動してから下記の動作を行いましょう。
formappの部分にはアプリ名が入ります。アプリ名も何でもOKです。今回はformappとしています。

##1-b. 下準備②コントローラーを用意する

```
 $ rails g controller helo
```

gの代わりに、generateでも構いません。コントローラー名も何でもOKです。

コントローラーを作ったら、その後以下のようにファイルを編集してください。

```helo_contoroller.rb
class HeloController < ApplicationController

 def index
   if request.post? then
     @title = 'Result'
     @msg = 'you typed: ' + params['input1'] + '.'
     @value = params['input1']
   else
     @title = 'Index'
     @msg = 'type text..'
     @value = ''
   end
 end
end
```
普通に/heloにアクセスする場合はGETアクセスですから「GETかPOSTか」をチェックしてそれによって処理を変えるような仕組みにしています。

>**【応用編】requestとpost?について**
ここでの「request」と言うのはクライアント(WEBサーバー)からサーバーに送られた情報をまとめたオブジェクトです。どう言う形でアクセスしたのか、
その細かな情報がこの中に入っています。そして、「post?」と言うのは「POST送信したかどうか」を示すメソッドです。
これがtrueならPOSTアクセスしており、falseならばPOSTアクセスしていない(つまりGET送信)と言うことになります。
送信されたフォームの内容は、paramsで得ることができます。
下記ビューファイルの中にある\<input type= "text" name="input1">の値はparams['input1']で取り出せることができます。



##1-c. 下準備③ビューを用意する

app/views/heloフォルダの中に新しく、右クリックして新しくindex.html.erbファイルを作りましょう。
そうしたらそのファイルの中に次のようにコードを書いてみてください。(コピペで構いません。)

```helo/index.html.erb

<h1><%= @title %></h1>
<p><%= @msg %></p>
<form method="POST" action= "/helo/index">
  <input type= "text" name="input1" value="<%= @value %>">
  <input type= "submit">
</form>

```

入力フィールドと送信ボタンがあるだけのコードです。
送信先は、/heloにPOST送信する形になっています。

>参照リンク：
[GETとPOSTの違い](https://wa3.i-3-i.info/diff7method.html)


##1-d. ルーティングを設定する

```config/routes.rb
Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  get 'helo/index'
  get 'helo', to: 'helo#index'
  post 'helo' , to: 'helo#index'
  post 'helo/index'
end
```
これで、/heloと/helo/indexにPOSTのアクセスが許可されます。
POSTでアクセスする場合は「post 〇〇」と言う具合に書けばOKです。

##1-e. InvalidAuthenticityTokenとCSRF対策

ここまでできたら、ターミナル(コマンドプロンプト)上で以下のようにしましょう。

```
 $ rails s
```
これで、http://localhost:3000/helo/index にアクセスしてみてください。

![Formapp_🔊.png](https://qiita-image-store.s3.amazonaws.com/0/200663/fd996f05-14c3-40a1-a557-64cde2a23d17.png)

おそらく、上記の画像のような画面になるでしょう。
次に、この画面上にあるボックスの中にテキストを打ち込み、フォームの送信を試すと次のようなエラー画面が出ませんか？


![Action_Controller__Exception_caught_🔊.png](https://qiita-image-store.s3.amazonaws.com/0/200663/aecf18a4-72d4-6124-0847-cdc7ef5e807b.png)

このエラーは、CSRF対策(Cross Site Request Forgery)のために発生したものになります。

>参照リンク
[CSRF対策](https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/301.html)


そんなエラーが出た時は、こちらの一文をコントローラーのclassの下に書きます。
このコードを書くことでCSRF対策を無効化することができます。

```
 protect_from_forgery
```
具体的にはこんな感じです。

```helo_controller.rb

class HeloController < ApplicationController
 protect_from_forgery
  
 def index
   if request.post? then
     @title = 'Result'
     @msg = 'you typed: ' + params['input1'] + '.'
     @value = params['input1']
   else
     @title = 'Index'
     @msg = 'type text..'
     @value = ''
  end
 end
end
```

これできっとうまくいくでしょう。入力した文字が出てくると思います。

![Formapp_🔊.png](https://qiita-image-store.s3.amazonaws.com/0/200663/52930d57-35de-025d-97ab-89bc3d51a7d8.png)


#2.Railsの「フォームヘルパー」機能を用いよう！

##2-a.フォームヘルパーの基本を知ろう！

ここまでで、フォームを送信し処理する基本はわかったかと思います。ただ、CSRF対策を無効化すると言うのはセキュリティ的に良くないので、次からはRailsのきちんとしたフォームの使い方を学んで行きましょう。

Railsにはフォームの作成を支援する「フォームヘルパー」と言うものがあります。
ヘルパーと言うのは、ビューで利用できる便利な機能のプログラムのことです。

それではどんどんやって行きましょう。
まず、helo/index.html.erbを以下のように編集しましょう。

```helo/index.html.erb

<h1><%= @title %></h1>
<p><%= @msg %></p>
<%= form_tag(controller: "helo" , action: "index") do %>
  <%= text_field_tag("input1") %>
  <%= submit_tag("Click") %>
<% end %>
```

そして次に、helo_controller.rbから、「protect_from_forgery」も消しましょう。

```helo_controller.rb
class HeloController < ApplicationController

 def index
   if request.post? then
     @title = 'Result'
     @msg = 'you typed: ' + params['input1'] + '.'
     @value = params['input1']
   else
     @title = 'Index'
     @msg = 'type text..'
     @value = ''
  end
 end
end
```

以下の画像のようになると思います。先ほどと同様に入力フィールドと送信ボタンのフォームが表示されます。
CSRF対策はきちんと機能していますが、フォームからの送信も問題なく表示されます。

![Formapp_🔊.png](https://qiita-image-store.s3.amazonaws.com/0/200663/edcfd3c2-8752-3d3e-dea8-f833028f8dee.png)

上のViewファイルのコードについて一個ずつ確認しましょう。

###①入力フィールド

```
 <%= text_field_tag("input1") %>
```

一般化すると、

```
 <%= text_field_tag(割り当てるID名) %>
```

引数にIDの値を指定して実行します。

###②送信ボタン

```
 <%= submit_tag("Click") %>
```

一般化すると、

```
 <%= submit_tag(ボタンのテキスト) %>
```

###③フォームの終了

```
 <% end %>
```

ここでの<% %>と言うタグは結果を表示するものではなく、単にRubyの文を実行するためのものです。
フォームの生成は整理すると以下のようになります。

```
 form_tag(〇〇) do
   ------コントロール関係を出力する文--------
 end
```


次から、フォームヘルパーの色々な種類について見ていきましょう。

##2-b.フォームヘルパーの応用【チェックボックス編】

テキストの入力フィールド以外のコントロール類の使い方も見てみましょう。
まず、helo/index.html.erbを以下のように編集してみましょう。

```helo/index.html.erb

<h1><%= @title %></h1>
<p><%= @msg %></p>
<%= form_tag(controller: "helo", action: "index") do %>
    <%= check_box_tag("check1") %>
    <%= label_tag("check1", "check box") %>
    <%= submit_tag("Click") %>
<% end%>
```

引数にはチェックボックスに割り当てるIDを指定。

```
<%= check_box_tag(割り当てるID) %>
```

<label>タグを出力するためのもの

```
<%= label_tag(割り当てるID, 表示するテキスト) %>
```

コントローラーも修正する必要があります。

```helo.controller.rb
class HeloController < ApplicationController

  def index
     if request.post? then
       @title = 'Result'
       if params['check1'] then
          @msg = 'you Checked!'
       else
          @msg = 'not checked!'
       end
     else
       @title = 'Index'
       @msg = 'check it'
     end
  end
end
```

うまく行けば下記画像のようになると思います。

![Formapp_🔊.png](https://qiita-image-store.s3.amazonaws.com/0/200663/b10e2927-4f49-7e24-8ede-f83edb9dc714.png)
![Formapp_🔊.png](https://qiita-image-store.s3.amazonaws.com/0/200663/e9c8902d-e509-6f4b-e611-a500558c4419.png)



##2-c.フォームヘルパーの応用【ラジオボタン編】

次に、ラジオボタンと言う複数の項目から１つを選択するのに用いられるフォームを作ってみましょう。
ラジオボタンは「radio_button_tag」と言うメソッドを使って作成可能です。

###ラジオボタンの作成

```
 radio_button_tag( name値 , value値 )
```
ラジオボタンに設定するnameの値と、選択したときに得られるvalueの値をそれぞれ引数に用意します。
IDは指定せずとも、nameとvalueから自動的に設定されます。フォームヘルパーでは、**「name値_value値」**と言うIDで設定されます。

それでは実際にラジオボタンを使ったフォームを作ってみましょう。
先ほど使ったindex.html.erbファイルを以下のように書きかえます。

```helo/index.html.erb
<h1><%= @title %></h1>
<p><%= @msg %></p>
<%= form_tag(controller: "helo", action: "index") do %>
    <%= radio_button_tag("r1", "radio 1") %>
    <%= label_tag("r1_radio_1", "Radio Button 1") %><br>
    <%= radio_button_tag("r1", "radio 2") %>
    <%= label_tag("r1_radio_2", "Radio Button 2") %><br>
    <%= submit_tag("Click") %>
<% end%>
``` 
ここではそれぞれのラジオボタンにラベルをつけています。ここでは、IDは「r1_radio_1」という風に設定されていますね。
ちなみに半角スペースはアンダーバーに変換されます。

次に、コントローラーの修正をします。

```hello.controller.rb
class HeloController < ApplicationController

  def index
     if request.post? then
       @title = 'Result'
       if params['r1'] then
          @msg = 'you selected: ' + params['r1'] 
       else
          @msg = 'not checked!'
       end
     else
       @title = 'Index'
       @msg = 'select radio button!'
     end
  end
end
```


ラジオボタンは選択したラジオボタンのvalueの値が送られてきます。paramsで値をそのまま取り出せばokです。
どれも選択されてない場合もあるので、if params['r1'] then　で値が存在するかどうかをチェックし、それから設定された値をチェックして処理を行うのが良いです。

まとめるとこんな感じになります。

###①ラジオボタンの作成

```
 radio_button_tag( name値, value値 )
```
###②ラベルの作成

```
 label_tag(割り当てるID, 表示テキスト)
```
繰り返しになりますが、ラジオボタンのIDはnameとvalueから自動生成されます。
ラベルを用意する場合は自動生成するIDを指定しないと行けません。

うまくいくとこんな感じに表示されます。

![Formapp_🔊.png](https://qiita-image-store.s3.amazonaws.com/0/200663/b7616bcc-e166-33eb-d7d3-7fa96985344c.png)
![Formapp_🔊.png](https://qiita-image-store.s3.amazonaws.com/0/200663/b94aafad-9d33-3599-1043-b01f1ba14948.png)


##2-d.フォームヘルパーの応用【選択リスト編】

続いて、選択リストを作ってみましょう。「select_tag」と言うメソッドで作成します。
とりあえず実際に作ってみましょう。
先ほどまで使っているhelo/index.html.erbファイルを以下のように編集してみましょう。

```helo.index.html.erb
<h1><%= @title %></h1>
<p><%= @msg %></p>
<%= form_tag(controller: "helo", action: "index") do %>
    <%= select_tag('s1',
        options_for_select(["Windows", "macOS", "Linux"])) %>
    <%= submit_tag("Click") %>
<% end%>
```
「options_for_select」と言うメソッドで、Windows、macOS、Linuxと言う項目の配列を渡し、これらのリストを作成しています。

簡単にまとめると、以下のようになります。

###選択リストの生成

```
 select_tag(割り当てるID, options_for_select(配列))
```
select_tagの中に、更にoptions_for_selectを用意して、表示する項目名を配列で指定します。

続いて、コントローラーの編集をしてみましょう。

```hello.controller.rb
class HeloController < ApplicationController

  def index
     if request.post? then
       @title = 'Result'
       if params['s1'] then
          @msg = 'you selected: ' + params['s1'] 
       else
          @msg = 'not selected!'
       end
     else
       @title = 'Index'
       @msg = 'select List!'
     end
  end
end
```
うまくいくと以下の画像のような画面になるでしょう。

![スクリーンショット 2018-08-13 16.14.16.png](https://qiita-image-store.s3.amazonaws.com/0/200663/cbfd81de-6c5b-3dd0-8f4b-d6de5a8295f4.png)

フォームヘルパーのまとめは以上になります。

間違いなどございましたら指摘いただけますと幸いです。