こんにちは、鈴木です。
Rails で独自のフォームビルダーを作ると便利なことがあります。
フォームビルダーとは
Rails でフォームを作成するときに form_for メソッドを使用しますが、form_for に渡すブロックの引数に渡されるオブジェクトがフォームビルダーです。
言葉では分かりづらいですが、以下のコードにおける「form」がそれです。
1 2 3 |
<%= form_for(@user) do |form| %> # ブロック引数の form がフォームビルダーです. <% end %> |
フォームビルダーの実体は ActionView::Helpers::FormBuilder クラスであり、ブロック引数に渡されるのは ActionView::Helpers::FormBuilder のインスタンスです。
普段「<%= form.text_field(:name) %>」のように便利に使っているメソッドは ActionView::Helpers::FormBuilder で定義されています。
error_message_on を書くのが面倒
ときどきですが、以下のように「form.text_field(...)」のように入力項目を作り、すぐ後に「form.error_message_on(...)」でエラーメッセージを表示する、というコードを何度も書くことがあります。
1 2 3 4 5 6 7 8 9 10 11 |
<%= form_for(@user) do |form| %> 名前: <%= form.text_field(:name) %> <%= form.error_message_on(:name) %> メールアドレス: <%= form.text_field(:email) %> <%= form.error_message_on(:email) %> ... <% end %> |
数が少ない場合は良いですが、入力項目の多いフォームだと「form.error_message_on(...)」を書くことが面倒になってきます。
そのようなときは、独自のフォームビルダーを作成し、自動的に「form.error_message_on(...)」を挿入するようにすると楽ができます。
※補足: Rails3 からは error_message_on や error_message_for は dynamic_form という Gem に外出しされましたので、使用する場合は Gemfile に dynamic_form を追加する必要があります。
独自のフォームビルダーを作る
独自のフォームビルダーを作るには、ActionView::Helpers::FormBuilder を継承したクラスを作成します。
とりあえず text_field に自動的に error_message_on を追加するようにコードを書いてみます。
1 2 3 4 5 6 7 |
class CustomFormBuilder < ActionView::Helpers::FormBuilder def text_field(attribute, options={}) super + error_message_on(attribute) end end |
「super」でデフォルトの処理を呼び出し、その結果に「error_message_on(attribute)」の結果を加えています。
作成した CustomFormBuilder を使用するには、以下のように form_for のオプション :builder で指定します。
1 2 3 4 5 6 7 8 |
<%= form_for(@user, :builder => CustomFormBuilder) do |form| %> 名前: <%= form.text_field(:name) %> メールアドレス: <%= form.text_field(:email) %> ... <% end %> |
text_field の後には自動的に error_message_on が挿入されるので、コードから error_message_on は消えています。
まとめ
今回は text_field メソッドをオーバーライドしましたが、実用的なライブラリに仕上げるには text_area や collection_select など他のメソッドもオーバーライドする必要があります。
また、オーバーライドではなく新しいメソッドを定義する、というように実現の仕方は一通りではありません。
プロジェクトごとにベストなやり方を考えてみましょう!
Comments
ナイスです。使ってみます!