実行環境:
Rails 3.0.7
ftext_field と text_field_tag の使い分けについて
Scaffold を作った時に自動的にできてくる View(_form.html.erb)を見ると
<%= form_for(@hoge) do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
ってな感じで f.text_field を使っています。
特定のモデルに結びついたフォームならこれでいいんですが、そうでない場合は form_for ではなく form_tag を使う、ってとこまでは理解していたんですが、form_tag の中の部品については text_field_tag を使う?でも text_field タグも使えちゃうみたいよ、どうすんだ??と漠然と疑問だったので調べてみました。
その結果は
- text_field グループ
⇒モデルを対象とするヘルパ
- text_field_tag グループ
⇒モデルには関連づけられず、値のみを対象とするヘルパ
まぁ、その通りでございますね (^^;;; やっぱり form_for の時は text_field グループを使う、form_tag の時は text_field_tag グループを使うってことで基本的にはいいようです。
しか〜し、これでは再確認しただけで当初の疑問は解決してまへん。もうちょっとつっこんで調べてみると、どうやら params への値の渡り方にポイントがあるようです。
結論としては
- text_field グループ
考え方:モデルを対象として、モデルの値を受け渡すためのフォーム部品
振舞い:params 変数に二次元のハッシュとして値を渡す
- text_field_tag グループ
考え方:モデルには関連づけず、値のみを単純に渡すフォーム部品
振舞い:params 変数に一次元のハッシュとして値を渡す
ということになります。
まとめるとそういうことなんですが、一応それぞれの場合を整理してみます。
| form_forの中で | form_tagの中で |
text_fieldグループを | ①(標準的) | ②(特殊?) |
text_field_tagグループを | ④(特殊?) | ③(標準的) |
① text_field グループを form_for 内で使う
Scaffold として作られる以下のようなフォームの場合、
<%= form_for(@hoge) do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
受け側で受け取るフォームの値は params[:hoge][:name] となります。 通常、モデルの作成や更新に使う場合
create アクション
@hoge = Hoge.new(params[:hoge])
update アクション
@hoge = Hoge.find(params[:id])
@hoge.update_attributes(params[:hoge])
といった具合で便利にできるので params の中身をことさらに気にする必要はないんですね。
② text_field グループを form_tag 内で使う場合
form_tag の中で text_field を使うときは少しパラメータの与え方が違って
form_tag の中で text_field
<%= form_tag url, options do %>
<%= text_field :hoge, :name, :value => 'default_name' %>
<%= submit_tag %>
<% end %>
という感じになります。form_tag の中で text_field という形で使うと1番目と2番目のパラメータが名前として使われ、params[:hoge][:name] に値が渡されます。 HTML としてはこんな感じで展開されます。
展開された HTML
<input type="text" id="hoge_name" name="hoge[name]" value="default_name" />
params にハッシュで構造化した値を渡したいときは便利かもしれません。どんな用途があるかパッと思いつきませんが。 ハッシュにしたくないよってときは強引ですが
form_tag の中で text_field
<%= form_tag url, options do %>
<%= text_field nil, nil, :id => name, :name => name, :value => 'default_name' %>
<% end %>
とすれば
展開された HTML
<input type="text" id="name" name="name" value="default_name" />
と展開されますが、それならおとなしく text_field_tag 使えばって話です (^^;
③ text_field_tag グループを form_tag 内で使う
form_tag の中で text_field_tag
<%= form_tag url, options do %>
<%= text_field_tag :name, :value => 'default_name' %>
<% end %>
とすると params[:name] に値が渡ります。
④ text_field グループを form_for 内で使う
まず、以下のような書き方はできません。
form_for の中で text_field_tag
<%= form_for(@hoge) do |f| %>
<%= f.text_field_tag :extra_text %>
<% end %>
form_for の中でも form_tag の中でも使い方や挙動は同じです。
form_for の中で text_field_tag
<%= form_for(@hoge) do |f| %>
<%= text_field_tag :name, :value => 'default_name' %>
<% end %>
とするとやはり params[:name] に値が渡ります。注意すべきは params[:hoge][:name] のように params[:hoge] 配下に入らないということです。
form_for の中で text_field_tag
<%= form_for(@hoge) do |f| %>
<%= text_field_tag :extra_text %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
という書いてやると、Hoge モデルに対応したパラメータ params[:hoge][:name] と、モデルとは関係ない params[:extra_text] を同時に渡せることになります。 場合によっては便利に使える気がします!(たぶん)