form_forの使い方をざっとまとめてみました

# form_forで出来ること 

from_forを使うことで入力フォームに必要なHTMLを作成することができます。
お問い合わせ画面とかで名前や内容等を入力する部分のとこです。

# 下準備
まずは、form_forを使っていく下準備としてscaffoldでモデルやコントローラー、ルーティング等を簡単に作っていきます。


```ruby:terminal
rails new training
cd training
rails g scaffold user name:string email:string 
rails db:migrate
```

今回は練習のためformヘルパーは使わずにフォームを作成していきたいと思うので
以下のように該当するviewを修正してください。

```html:/training/app/views/users/new.html.erb(ユーザー新規登録画面)

<h1>New User</h1>

<%= form_for @user do |f| %>
  <%= f.label :name %>
  <%= f.text_field :name %>
  
  <%= f.label :email %>
  <%= f.email_field :email %>
  
  <%= f.submit '送信' %>
<% end %>

```

# 使い方と処理の流れ

今回は、ユーザー新規登録時に新しくデータを入力する際のケースについて書いていきます。

#### 1.コントローラー内で空のオブジェクトを生成する。

さきほどコマンドでscaffordを実行したので自動的にusersコントローラー内にCRUDに関するメソッドが書かれていると思います。
実際にusersコントローラーを確認してみましょう。

```ruby:/training/app/controllers/users_controller.rb
# GET /users/new
  def new
    @user = User.new
  end
```
一部抜粋ですが、usersコントローラーのnewメソッド内では空のUserモデルを作ってそれを@userインスタンス変数に代入しています。

#### 2.viewにフォームを書く

次に、該当するviewにフォームを書いていきます。@userインスタンス変数をform_forに引数として渡します。

```html:/training/app/views/users/new.html.erb(ユーザー新規登録画面)
<h1>New User</h1>
 
<%= form_for @user do |f| %>
  <%= f.label :name %>
  <%= f.text_field :name %>
  
  <%= f.label :email %>
  <%= f.email_field :email %>
  
  <%= f.submit '送信' %>
<% end %>
```
- form_forメソッドの書き方
`fomr_for モデルクラスのオブジェクト　do |f|`
が基本になります。
以下のように、引数に（）を付けることも出来ます
`fomr_for (@user)　do |f|`

- 入力フォームの構造
`f.htmlタグ名　：カラム名`

書き終わったら画面でHTMLの中身を確認してみましょう。
以下のように表示されているはずです。

```html:HTML
<form class="new_user" id="new_user" action="/users" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="0+Ifi1D0zy2bXJ6LIIjlxgXuLXJFiziznUA+tbFXk2eq2FPzSVDooaqgmNCsHuwljm25T9dcXUGVuAk+RZ/b/g==">
  <label for="user_name">Name</label>
  <input type="text" name="user[name]" id="user_name">
  
  <label for="user_email">Email</label>
  <input type="email" name="user[email]" id="user_email">
  
  <input type="submit" name="commit" value="送信" data-disable-with="送信">
</form>
```
- inputタグ内の説明

inputタグ内のaction属性とmethod属性のそれぞれの属性値の意味について確認します。
actionの属性値　→ 送信先のパス
methodの属性値 → httpメソッド(get,postなど…）

今回の例で当てはめると以下のようになります
action="/users"  → 送信先のパスが `/users`
method="post"   → 使用されるhttpメソッドが `post`

※HTMLのinputタグ内のname属性値は`モデル名[カラム名]`の構造になっています。

- createアクションかupdateアクションを実行する際の基準

form_forに渡されたオブジェクトが何も情報が入っていない場合（オブジェクトがnilの場合）はcreateアクションを送るようにform_for側で自動的に判断してくれます。
反対に、オブジェクトに何か値が入っている場合はupdateアクションを自動的に振り分けてくれます。
また、引数にgetやpostなどのhttpメソッドは書いても書かなくてもどちらでも構いません。

- form_forで使用できる主なタグ
    - f.label　　　　対応するラベルを作成
    - f.text_field　　一行のテキスト投稿フォーム
    - f.text_area　　複数行のテキスト投稿フォーム
    - f.email_field    　メールアドレス用のフォーム
    - f.check_box 　チェックボックス
    - f.file_field    　 　画像アップロード時などのファイル選択ボックス
    -  f.submit        　　　送信ボタン

他にも色々あるので必要なものは適宜調べてみてください！


#### 3.送信ボタンを押した後は、入力された値をparams変数にハッシュ形式で渡す
`2.viewにフォームを書く`で説明したHTML内のinputタグのname属性をキーとしてparams変数にハッシュ形式で値を渡します。
今回はnameフォームに”hoge",emailフォームに"hogehoge@mail.com"と入力してみました。

```ruby:
params = {
    user: {
      name: "hoge"
     ,email: "hogehoge@mail.com"
       }
}
```

#### 4.ストロングパラメータでparamsの値を引き出し、createアクション内のnewメソッドに引数として渡す。

ストロングパラメータに関する説明は長くなりそうなのでまた別の記事で書こうと思うので割愛しますが、こちらではpermitで書かれているパラメーターのみが登録の対象となります。
したがって、age:20とかを登録することは出来ません。

```ruby:
  # POST /users
  # POST /users.json
  def create
　　 # user_params(ストロングパラメータ)を呼び出す
    @user = User.new(user_params)

    respond_to do |format|
      if @user.save
        # redirect_to @user は user_path(@user)と同義
        format.html { redirect_to @user, notice: 'User was successfully created.' }
        format.json { render :show, status: :created, location: @user }
      else
        format.html { render :new }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

private

    # Never trust parameters from the scary internet, only allow the white list through.
　　 #params変数内でpermit（許可）された値のみを呼び出し元に渡す。
    def user_params
      params.require(:user).permit(:name, :email)
    end
```

# 最後に
誤っている箇所や追記した方が良い点等ございましたら
編集リクエストやコメントの方でご指摘していただけると幸いです。

参考
[【Rails】form_forの使い方を徹底解説！](https://www.pikawaka.com/rails/form_for)
[Railsのform_forを使ったフォームのController,View,Modelの連携した処理フロー](https://ruby-rails.hatenadiary.com/entry/20140727/1406448610)