読者です 読者をやめる 読者になる 読者になる

Railsのform_tagで生成されるHTML

Railsのform_tagメソッドがどのようなHTMLを生成するのか整理。

前提

rails 3.2
ruby 1.9.2(ハッシュの書き方は新verで)

まず

  • Railsでは、form要素を生成するヘルパーメソッドとして、form_tagとform_forという2種類のメソッドが用意されている
  • form_tagは、汎用的なformを作るためのメソッド(特定のモデルに特化しない検索とか)
  • form_forは、特定のモデルに特化したformを作るためのメソッド
  • ここでは、form_tagがどのようなHTMLを生成するのかを整理する

form_tag

一番シンプルな形
<%= form_tag do %>
  formの中身
<% end %>

<form accept-charset="UTF-8" action="今の画面のURL" method="post">
  <div style="margin:0;padding:0;display:inline">
    <input name="utf8" type="hidden" value="&#x2713;" />
    <input name="authenticity_token" type="hidden" value="トークン" />
  </div>
  formの中身
</form>

すっぴんでも、デフォルトで色々ついてくる

  • action属性のデフォルト値は、今の画面のURL
  • method属性のデフォルト値は、post
  • hiddenタイプのinput要素が2つ、自動生成される(utf8とauthenticity_token)
  • name=utf8は、サーバーが文字コードの判別を適切に実行するためのもの。GETでもPOSTでも必ず付加される
  • name=authenticity_tokenは、CSRF対策のトークン。GET以外の時は必ず付加される
actionを指定
<%= form_tag("/hoge") do %>
  formの中身
<% end %>

<form accept-charset="UTF-8" action="/hoge" method="post">
  <div style="margin:0;padding:0;display:inline">
    <input name="utf8" type="hidden" value="&#x2713;" />
    <input name="authenticity_token" type="hidden" value="トークン" />
  </div>
  formの中身
</form>
mehodを指定
<%= form_tag("/hoge", method: "get") do %>
  formの中身
<% end %>

<form accept-charset="UTF-8" action="/hoge" method="get">
  <div style="margin:0;padding:0;display:inline">
    <input name="utf8" type="hidden" value="&#x2713;" />
  </div>
  formの中身
</form>
  • GETにすると、input name=authenticity_token...は付加されない
id,name,classを追加
<%= form_tag("/hoge", method: "get", id: "hoge_id", name: "hoge_name", class: "hoge_class") do %>
  formの中身
<% end %>

<form accept-charset="UTF-8" action="/hoge" class="hoge_class" id="hoge_id" method="get" name="hoge_name">
  <div style="margin:0;padding:0;display:inline">
    <input name="utf8" type="hidden" value="&#x2713;" />
  </div>
  formの中身
</form>
引数2つというのがポイント
  • form_tagメソッドは引数を2つ
  • 第1引数がaction属性で、第2引数がその他の属性
  • Railsではハッシュの外側の中括弧をしばしば省略する
  • なので、以下の構文は同じ
<%= form_tag("/hoge", method: "get", id: "hoge_id", name: "hoge_name", class: "hoge_class") do %>
  formの中身
<% end %>

⇅同じ

<%= form_tag(
  "/hoge",
  {
    method: "get",
    id: "hoge_id",
    name: "hoge_name",
    class: "hoge_class"
  }
) do %>
  formの中身
<% end %>
第1引数にもハッシュが使える
  • form_tagの第1引数(actionの値になる)は文字列でなく、link_toヘルパーと同じくルーティングのハッシュを入れることができる
  • 例えばusersコントローラにsearchアクションがルーティング設定されているとしたら、以下のように書ける
<%= form_tag(
  {
    controller: "users",
    action: "search",
    id: 1
  }, 
  {
    method: "get",
    id: "hoge_id",
    name: "hoge_name",
    class: "hoge_class"
  }
) do %>
  formの中身
<% end %>

<form accept-charset="UTF-8" action="/users/1/search" class="hoge_class" id="hoge_id" method="get" name="hoge_name">
  <div style="margin:0;padding:0;display:inline">
    <input name="utf8" type="hidden" value="&#x2713;" />
  </div>
  formの中身
</form>

以上

form_forについてはまた今度調べる

参考

公式のドキュメントが一番正確
http://guides.rubyonrails.org/form_helpers.html

htmlのformについてしっかり理解したいときには
http://www.kanzaki.com/docs/html/htminfo31.html