LoginSignup
11
17

More than 5 years have passed since last update.

form_tagとform_forの違い

Last updated at Posted at 2018-11-12

form_for

「モデルの新規インスタンスに値を追加して保存」したい場合はform_for

form_forは、特定の「モデル」を編集・追加するためのフォームを生成するヘルパーメソッド。
特定のテーブルにレコード(モデルクラスのインスタンス)だけを新規作成、更新するときに利用する。

このような特性があるので、form_tagとform_forは下記のように使い分ける。

■form_for: 任意のモデルに基づいたformを作るときに使う(投稿フォームなど)
→フォームに入力した情報をモデルを通じて、テーブルに追加・編集する
■form_tag: モデルに基づかないformを作るときに使う(検索フォームなど)
→検索は別にモデルに編集やインスタンスの追加をする必要はない

(使い方)

form_for.rb
<%= form_for(モデルクラスのインスタンス) do |f| %><% end %>

form_forは引数のインスタンスが何も情報を持っていなければ自動的にcreateアクションへ、すでに情報を持っている場合はupdateアクションへ自動的に振り分けてくれる。form_tagのようにルーティングパスを指定する必要がないのでラク。

モデルクラスのインスタンスはコントローラで予め定義しておくこと!

form_for内で使うメソッドは、f.htmlタグ名 :カラム名の形で指定

【form_forにおけるメソッドの例】

メソッド           用途           
f.label labelのlabelタグを表示 
f.text_field textのinputタグを表示
f.date_select モデルで設定したフィールドをselectタグで選べるようにして表示  
f.check_box checkboxのinputタグを表示
f.number_field numberのinputタグを表示
f.submit submitのinputタグを表示

参照URL:http://railsdoc.com/form

sample.rb
    <%= form_for [@product, @review] do |f| %>
          <div style="margin: 8px 0">
            <%= f.label :nickname, style: { 'margin-right' => 8 } %>
            <%= f.text_field :nickname, placeholder: 'nickname', value: '' %>
          </div>
          <div style="margin: 8px 0">
            <%= f.label :評価, style: { 'margin-right' => 8 } %>
            <%= f.number_field :rate, placeholder: '評価', value: 1, max: 10, min: 1, html: { class: "search__query", style: 'text-align: right;' } %>
          </div>
          <div style="margin: 8px 0">
            <%= f.text_area :review, placeholder: 'レビューを書いてね!', style: 'width: 100%;height: 300px;' %>
          </div>
          <div class="row">
            <div class="col10 push1">
              <%= button_tag type: "submit", class: "btn btn--block" do %>
              投稿する<i class="icon-arrow-right"></i>
              <% end %>
            </div>
          </div>
      <% end %>

1行目のform_forの引数が配列になっている。配列の1つ目の要素のインスタンスのidがパスの:product_idに入る。今回はパスのネストが2段階なので、form_forの引数のインスタンスは2つ。

form_forの引数について

resourcesを2回ネストした場合

routes.rb
resources :users do
  resources :products do
    resources :reviews
  end
end
controller.rb
def new
  @user = User.find(4)
  @product = Product.find(2)
  @review = Review.new
end
new.html.erb
<%= form_for ( [@user, @product, @review ] ) do |f| %>
  (中略)
<% end %>
送られるリクエスト
↓↓
# HTTPメソッド
POST
# パス
/users/4/product/2/reviews

form_tagとform_forでのパラメータへの保存方法の違い

binding.pryを使ってparamsを見るとよく分かるが、form_forはparamsのハッシュの中に別のハッシュが内包されており、ハッシュの二重構造が存在している状態になっている。

alt

ターミナルで見るとこんな感じ
↓↓↓↓

>>>new.html.erb
<%= form_for(@book) do |f| %>
  <%= f.text_field :name %>
  <%= f.text_area :detail %>
<% end %>

>>>ターミナル
params
# { book: { name: "入力された名前", detail: "入力された詳細" } }

※上の例のbookはモデル名

なので、これらをハッシュをまずは分離してあげる必要がある。そこで使用するので、「require」メソッド。これを利用することで、ストロングパラメータを設定することができる。

<requireメソッド>
params.require(:モデル名).permit(:カラム名)
→これでparamsの中からモデル名(book)のハッシュ({ name: "入力された名前", detail: "入力された詳細" })を呼び出している

【参照URL】
https://qiita.com/tsubasakat/items/4ececaba4efc928c0792
https://www.sejuku.net/blog/13163

11
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
17