Last-modified: 2010-09-22 (水) 16:37:55 (11h)
Rails Form helpers †
原文 †http://guides.rubyonrails.org/form_helpers.html フォームヘルパ(Rails Form helpers) †Web アプリケーション内のフォームは、ユーザーの入力のための本質的なインターフェイスです。 このガイドでは:
このガイドは、利用可能なフォームヘルパーとその引数の完全なドキュメントであることを意図されていません。 1 基本的なフォームの処理(Dealing with Basic Forms) †最も基本的なフォームヘルパーはのform_tagです。 <%= form_tag do %> Form contents <% end %> このように、引数なしで呼ばれた場合、 form_tag のサンプル出力: <form action="/home/index" method="post"> <div style="margin:0;padding:0"> <input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" /> </div> Form contents </form> この出力を注意深く観察すると、あなたが指定していない何かをヘルパが生成していることに気づくでしょう: このガイド内では、わかりやすいコードサンプルのために、この hidden の input を持つ div は省略されます。 1.1 汎用検索フォーム(A Generic Search Form) †しばしば、ウェブ上で見られるおそらく最小のフォームは、検索する言葉のための単一テキスト入力がある検索フォームです。
検索フォームのメソッドとして "GET" を常に使うべきです。 このフォームを作るために、 form_tag 、 label_tag 、 text_field_tag 、 submit_tag をそれぞれ使うでしょう。 基本的な検索フォーム <%= form_tag(search_path, :method => "get") do %> <%= label_tag(:q, "Search for:") %> <%= text_field_tag(:q) %> <%= submit_tag("Search") %> <% end %> search_path は "routes.rb" 内で指定された名前付きルートでしょう: 上記のビューのコードは次のマークアップになります: <form action="/search" method="get"> <label for="q">Search for:</label> <input id="q" name="q" type="text" /> <input name="commit" type="submit" value="Search" /> </form> text_field_tag と submit_tag に加えて、 HTML 内のすべてのフォームコントロールのための、同様のヘルパーがあります。 全てのフォームの入力では、 ID 属性は、その名前から生成されます。(例では "q" ) 1.2 フォームヘルパ呼び出し中の複数のハッシュ(Multiple Hashes in Form Helper Calls) †今では form_tag ヘルパは2つの引数を受け取ることを見ました:アクションのパスと、オプションのハッシュです。 link_to ヘルパと同様に、パス引数は必ずしも文字列を指定される必要はありません。 form_tag(:controller => "people", :action => "search", :method => "get", :class => "nifty_form") # => <form action="/people/search?method=get&class=nifty_form" method="post"> ここで、二つのハッシュを渡したいが、 Ruby インタプリタは一つのハッシュしか見ていません。 form_tag({:controller => "people", :action => "search"}, :method => "get", :class => "nifty_form") # => <form action="/people/search" method="get" class="nifty_form"> これは、フォームヘルパーを使用する上でよくある落とし穴で、それら多くは複数のハッシュを受け入れるからです。 最初のハッシュを区切ること無しに、第二のハッシュの区切らないで下さい。 1.3 フォーム要素を生成するためのヘルパ(Helpers for Generating Form Elements) †Rails は、チェックボックス、テキストフィールド、ラジオボタンのような <%= text_field_tag(:query) %> コントローラーのコードが、ユーザーによって入力された値の検索するのに使用するべきです。 params[:query] 入力を名付ける時、値が params ハッシュのトップレベルなのか、配列やネストしたハッシュの内側なのか 1.3.1 チェックボックス チェックボックスは、ユーザーに有効または無効に出来るオプションのセットを与えるフォームコントロールです: <%= check_box_tag(:pet_dog) %> <%= label_tag(:pet_dog, "I own a dog") %> <%= check_box_tag(:pet_cat) %> <%= label_tag(:pet_cat, "I own a cat") %> 出力: <input id="pet_dog" name="pet_dog" type="checkbox" value="1" /> <label for="pet_dog">I own a dog</label> <input id="pet_cat" name="pet_cat" type="checkbox" value="1" /> <label for="pet_cat">I own a cat</label> check_box_tag の2番目のパラメータは、入力の value です。 1.3.2 ラジオボタン ラジオボタンは、チェックボックスに似ていますが、 <%= radio_button_tag(:age, "child") %> <%= label_tag(:age_child, "I am younger than 21") %> <%= radio_button_tag(:age, "adult") %> <%= label_tag(:age_adult, "I'm over 21") %> 出力: <input id="age_child" name="age" type="radio" value="child" /> <label for="age_child">I am younger than 21</label> <input id="age_adult" name="age" type="radio" value="adult" /> <label for="age_adult">I'm over 21</label> radio_button_tag の2番目のパラメータは、 check_box_tag と同様に、入力の value です。 常に、チェックボックスとラジオボタン全てにラベルを使用して下さい。 1.4 興味深いその他のヘルパ(Other Helpers of Interest) †特筆すべきその他のフォームコントロールは、テキストエリア、パスワード入力、隠し入力です: <%= text_area_tag(:message, "Hi, nice site", :size => "24x6") %> <%= password_field_tag(:password) %> <%= hidden_field_tag(:parent_id, "5") %> 出力: <textarea id="message" name="message" cols="24" rows="6">Hi, nice site</textarea> <input id="password" name="password" type="password" /> <input id="parent_id" name="parent_id" type="hidden" value="5" /> 隠し入力はユーザーに表示されませんが、任意のテキスト入力のようなデータを保持します。 (任意の目的のために)パスワードの入力フィールドを使用している場合 2 モデルオブジェクトの処理(Dealing with Model Objects) †2.1 モデルオブジェクトのヘルパ(Model Object Helpers) †フォームの特に一般的なタスクは、モデルオブジェクトを編集することや作成することです。 これらのヘルパについて、最初の引数はインスタンス変数の名前で、 <%= text_field(:person, :name) %> は、以下のような出力を生成するでしょう。 <input id="person_name" name="person[name]" type="text" value="Henry"/>
上のフォーム送信で、ユーザーによって入力された値は、 params[:person][:name] 内に格納されるでしょう。 モデルオブジェクトの実際のインスタンスでは無く、 Rails は、モデルオブジェクトに関連付いたバリデーションエラーを表示するためのヘルパーを提供します。 2.2 オブジェクトへのフォームのバインド(Binding a Form to an Object) †快適さは増しているとはいえ、完璧にはほど遠いです。 記事を扱うコントローラー app/controllers/articles_controller.rb があると仮定すると: def new @article = Article.new end 対応するビュー、 app/views/articles/new.html.erb はこのように form_for を使っています。 <%= form_for :article, @article, :url => { :action => "create" }, :html => {:class => "nifty_form"} do |f| %> <%= f.text_field :title %> <%= f.text_area :body, :size => "60x12" %> <%= submit_tag "Create" %> <% end %> いくつかの注意があります:
結果の HTML は: <form action="/articles/create" method="post" class="nifty_form"> <input id="article_title" name="article[title]" size="30" type="text" /> <textarea id="article_body" name="article[body]" cols="60" rows="12"></textarea> <input name="commit" type="submit" value="Create" /> </form> form_for に渡された名前は、フォームの値にアクセスするための params 内で使われるキーをコントロールします。 フォームビルダ上で呼ばれたヘルパーメソッドは、編集されたオブジェクトを除いて、モデルオブジェクトヘルパと同一です。 実際に <form> タグを作ることなく、 fields_for ヘルパーで同様のバインディングを作成することができます。 <%= form_for :person, @person, :url => { :action => "create" } do |person_form| %> <%= person_form.text_field :name %> <%= fields_for @person.contact_detail do |contact_details_form| %> <%= contact_details_form.text_field :phone_number %> <% end %> <% end %> 次の出力を生成します: <form action="/people/create" class="new_person" id="new_person" method="post"> <input id="person_name" name="person[name]" size="30" type="text" /> <input id="contact_detail_phone_number" name="contact_detail[phone_number]" size="30" type="text" /> </form> fields_for によって yield されているオブジェクトは、form_for によって yield されているオブジェクトのようなフォームビルダです。 2.3 レコード識別の依存(Relying on Record Identification) †Article モデルはアプリケーションのユーザーが直接利用できます - 続く Rails で開発するためのベストプラクティス - map.resources :articles リソースを宣言することは、副作用があります。 RESTful なリソースを扱う時、レコード識別に依存しているなら、 form_for の呼び出しが大幅に容易に得ることができます。 ## 新しい記事の作成 # 長いスタイル: form_for(:article, @article, :url => articles_path) # 同じ, 短いスタイル (レコード識別の利用): form_for(@article) ## 既存の記事の編集 # 長いスタイル: form_for(:article, @article, :url => article_path(@article), :html => { :method => "put" }) # 短いスタイル: form_for(@article) 短いスタイルの form_for の呼び出し方は、レコードを新しく作成する場合、既存の場合に関わらず、同様で、 Rails はまた自動的で適切に、フォームの class と id を設定します: モデル内で STI (単一テーブル継承)を使う時、親クラスがリソース宣言されている場合のみレコード識別を使うことが出来せん。 2.3.1 名前空間の処理 名前空間のルートを作成した場合、 form_for には気の利いた省略があります。 form_for [:admin, @article] admin 名前空間内の articles controller に送信するフォームを作成するでしょう。 form_for [:admin, :management, @article] Rails のルーティングシステムの詳細、関連する規則については、 routing guide を見てください。 2.4 PUT や DELETE メソッドとフォームがどのように働くか?(How do forms with PUT or DELETE methods work?) †Rails フレームワークは、アプリケーションの RESTful 設計を奨励し、 Rails は、目的のメソッドを反映するために設定された _method という名前の隠し入力を、 form_tag(search_path, :method => "put") 出力: <form action="/search" method="post"> <div style="margin:0;padding:0"> <input name="_method" type="hidden" value="put" /> <input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" /> </div> ... POST されたデータを解析する時、 HTTP メソッドが内部で指定されたなら(この例では "PUT" ) 3 簡単にセレクトボックスを作る(Making Select Boxes with Ease) †HTML 内のセレクトボックスは、かなりの量のマークアップ(選択するための各オプションごとに1つのオプション要素)を必要とし、 マークアップはこのようになります: <select name="city_id" id="city_id"> <option value="1">Lisbon</option> <option value="2">Madrid</option> ... <option value="12">Berlin</option> </select> ここでは、ユーザーに提示される名前の都市のリストがあります。 3.1 select と option タグ(The Select and Option Tags) †最も一般的なヘルパーは、 select_tag で - その名称が示すように - 単に <%= select_tag(:city_id, '<option value="1">Lisbon</option>...') %> これがスタートですが、動的にオプションのタグが作成されません。 <%= options_for_select([['Lisbon', 1], ['Madrid', 2], ...]) %> 出力: <option value="1">Lisbon</option> <option value="2">Madrid</option> ... options_for_select の最初の引数はネストされた配列です。 これを知っている場合は、望みを達成するために select_tag と options_for_select を組み合わせることができます。 <%= select_tag(:city_id, options_for_select(...)) %> options_for_select は値を渡すことによって、オプションを事前に選んでおけます。 <%= options_for_select([['Lisbon', 1], ['Madrid', 2], ...], 2) %> 出力: <option value="1">Lisbon</option> <option value="2" selected="selected">Madrid</option> ... Rails はその option の内部 value がこの値にマッチするものを生成したのを見つけたら、オプションに selected 属性を追加します。 options_for_select の2番目の引数は、正確に希望する内部の value に等しくなければなりません。 3.2 モデルを処理するセレクトボックス(Select Boxes for Dealing with Models) †ほとんどの場合、フォームコントロールは、特定のデータベースモデルに縛られるので、 # controller: @person = Person.new(:city_id => 2) # view: <%= select(:person, :city_id, [['Lisbon', 1], ['Madrid', 2], ...]) %> 三番目のパラメータ、オプションの配列、は options_for_select に渡したのと同じ種類の引数であることに注意して下さい。 他のヘルパーと同様に、
@person オブジェクトのスコープのフォームビルダー上の select ヘルパーを使用した場合、構文はこうなります: # select on a form builder <%= f.select(:city_id, ...) %> belongs_to アソシエーションを設定するために、 select (もしくは collection_select 、 select_tag のような類似したヘルパ)を使っている場合、 3.3 任意のオブジェクトのコレクションからオプションタグ(Option Tags from a Collection of Arbitrary Objects) †options_for_select が生成したオプションのタグは、あなたが各オプションのためにテキストと値を含む配列を作成することを、必要とします。 <% cities_array = City.all.map { |city| [city.name, city.id] } %> <%= options_for_select(cities_array) %> これは完全に有効なソリューションですが、 options_from_collection_for_select の冗長な代替です。 <%= options_from_collection_for_select(City.all, :id, :name) %> 名前が示すとおり、これは option タグを生成するだけです。 <%= collection_select(:person, :city_id, City.all, :id, :name) %> 要約すると、 options_for_select が select のための用途なのと同じように、 options_for_select に渡されるペアは、1番目に name と2番目に id を持っているべきです。 3.4 タイムゾーンと国の選択(Time Zone and Country Select) †Rails がサポートしているタイムゾーンを活用するには、どのようなタイムゾーンはいるかユーザーに尋ねる必要があります。 <%= time_zone_select(:person, :time_zone) %> また、これをするもっと手動(したがって、よりカスタマイズ可能)の方法として、 time_zone_options_for_select ヘルパーがあります。 Rails は国を選択するために country_select ヘルパーを使いますが、 4 日付と時刻のフォームヘルパーの使用(Using Date and Time Form Helpers) †日付と時刻のヘルパーは、2つの重要な点で他のすべてのフォームヘルパーとは異なります:
これら両方のヘルパーファミリは、様々なコンポーネント(年、月、日、等)のための一連のセレクトボックスを作ります。 4.1 ヘルパーの要点(Barebones Helpers) †select_* ヘルパファミリーは、 Date 、 Time 、 DateTime のインスタンスを第一引数としてとり、 <%= select_date Date.today, :prefix => :start_date %> 出力(簡潔にするため省略された実際のオプションの値) <select id="start_date_year" name="start_date[year]"> ... </select> <select id="start_date_month" name="start_date[month]"> ... </select> <select id="start_date_day" name="start_date[day]"> ... </select> 上記入力は、 :year 、 :month 、 :day がキーのハッシュである params[:start_date] 内に結果を出します。 Date.civil(params[:start_date][:year].to_i, params[:start_date][:month].to_i, params[:start_date][:day].to_i) :prefix オプションは、 params ハッシュから日付コンポーネントのハッシュを取得するために使用されるキーです。 4.2 モデルオブジェクトヘルパ(Model Object Helpers) †Active Record は、 params ハッシュの全ての要素が一つの属性に対応すると期待するので、 <%= date_select :person, :birth_date %> 出力(簡潔にするため省略された実際のオプションの値) <select id="person_birth_date_1i" name="person[birth_date(1i)]"> ... </select> <select id="person_birth_date_2i" name="person[birth_date(2i)]"> ... </select> <select id="person_birth_date_3i" name="person[birth_date(3i)]"> ... </select> params ハッシュ内の結果は {:person => {'birth_date(1i)' => '2008', 'birth_date(2i)' => '11', 'birth_date(3i)' => '22'}} これが Person.new (か update_attributes )に渡された時、 Active Record は 4.3 一般的なオプション(Common Options) †ヘルパーの両方のファミリーが、独立した select タグを生成する関数の同じコアセットを使い、両方ほぼ同じオプションを受け入れます。 経験則としては、モデルオブジェクトで動いてる場合は、 date_select を使用すべきで、 多くの場合、組み込みの日付ピッカーは、日付と曜日の間の関係を算出するのを支援しないため、使いにくいです。 4.4 個々のコンポーネント(Individual Components) †時折、年や月等、単一の日付コンポーネントだけを表示したいでしょう。 最初のパラメータはどの値が選択されるべきかを指定するでしょう。 <%= select_year(2009) %> <%= select_year(Time.now) %> は、現在の年が 2009 年なら同じ出力を生成します。 5 ファイルのアップロード(Uploading Files) †一般的なタスクは、人の写真や、処理するためのデータを格納している CSV ファイルであろうとなかろうと、 続く二つのフォームはどちらもファイルをアップロードします。 <%= form_tag({:action => :upload}, :multipart => true) do %> <%= file_field_tag 'picture' %> <% end %> <%= form_for @person, :html => {:multipart => true} do |f| %> <%= f.file_field :picture %> <% end %> Rails はヘルパーの通常のペアを提供しています:飾り気のない file_field_tag とモデル指向の file_field です。 5.1 アップロードされたものの取得(What Gets Uploaded) †params ハッシュ内のオブジェクトは IO のサブクラスのインスタンスです。 def upload uploaded_io = params[:person][:picture] File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 'w') do |file| file.write(uploaded_io.read) end end いったんファイルがアップロードされると、潜在的なタスクが沢山あり、 ユーザーがファイルを選択していない場合、対応するパラメータは空の文字列になります。 5.2 Ajaxでの処理(Dealing with Ajax) †他のフォームとは異なり、非同期のファイルのアップロードフォームを作ることは、 6 フォームビルダのカスタマイズ(Customising Form Builders) †前述のように、 form_for と fields_for によって yield されたオブジェクトは <%= form_for @person do |f| %> <%= text_field_with_label f, :first_name %> <% end %> は、以下で置き換えられます。 <%= form_for @person, :builder => LabellingFormBuilder do |f| %> <%= f.text_field :first_name %> <% end %> LabellingFormBuilder クラスを次のように定義することによって: class LabellingFormBuilder < ActionView::Helpers::FormBuilder def text_field(attribute, options={}) label(attribute) + super end end 頻繁に再利用する場合、 :builder => LabellingFormBuilder オプションを自動的に適用する フォームビルダーは、以下のことをしたとき、何が起こるか決定するために使います <%= render :partial => f %> f が FormBuilder のインスタンスであるなら、これはフォームパーシャルをレンダリングし、 7 パラメータの命名規則について理解する(Understanding Parameter Naming Conventions) †前のセクションで見てきたように、 根本的に、 HTML フォームは、構造化データの並べ替えについては知らず、 Rails のパラメータパーサーを直接呼び出すためにコンソールを使うことによって、 ActionController::UrlEncodedPairParser.parse_query_parameters "name=fred&phone=0123456789" # => {"name"=>"fred", "phone"=>"0123456789"} 7.1 基本的な構造(Basic Structures) †2つの基本的な構造は、配列とハッシュです。 <input id="person_name" name="person[name]" type="text" value="Henry"/> params ハッシュは、以下を含むでしょう。 {'person' => {'name' => 'Henry'} } また params[:person][:name] はコントローラー内で送信された値を取得するでしょう。 ハッシュは、必要なだけのレベルのネストができます、例えば: <input id="person_address_city" name="person[address][city]" type="text" value="New York"/> params ハッシュ内の結果は {'person' => {'address' => {'city' => 'New York'} } } 通常 Rails は、重複しているパラメータ名を無視します。 <input name="person[phone_number][]" type="text"/> <input name="person[phone_number][]" type="text"/> <input name="person[phone_number][]" type="text"/> この結果は、 params[:person][:phone_number] に配列で格納されます。 7.2 それらの合成(Combining Them) †これら二つの概念を混ぜあわせ、マッチさせることができます。 <input name="addresses[][line1]" type="text"/> <input name="addresses[][line2]" type="text"/> <input name="addresses[][city]" type="text"/> これは params[:addresses] 内に、 line1 、 line2 、 city をキーに持つ、ハッシュの配列が結果入るでしょう。 制限はありません、しかしながら、ハッシュは任意のネストにできますが、 "配列" は1レベルだけ許されます。 配列のパラメータは check_box ヘルパでは上手く動きません。 7.3 フォームヘルパーの利用(Using Form Helpers) †前のセクションでは、 Rails のフォームヘルパを全く使いませんでした。 person の address のそれぞれについて、 edit フィールドのセットがあるフォームをレンダリングしたいかもしれません。 <%= form_for @person do |person_form| %> <%= person_form.text_field :name %> <% for address in @person.addresses %> <%= person_form.fields_for address, :index => address do |address_form|%> <%= address_form.text_field :city %> <% end %> <% end %> <% end %> person が id 23 と 45 の二つの address を持っていると仮定すると、このような出力が出来ます: <form action="/people/1" class="edit_person" id="edit_person_1" method="post"> <input id="person_name" name="person[name]" size="30" type="text" /> <input id="person_address_23_city" name="person[address][23][city]" size="30" type="text" /> <input id="person_address_45_city" name="person[address][45][city]" size="30" type="text" /> </form> params ハッシュ内の結果は {'person' => {'name' => 'Bob', 'address' => { '23' => {'city' => 'Paris'}, '45' => {'city' => 'London'} } } } 最初のフォームビルダ上で fields_for を呼んだので、 Rails は、これらすべての入力は person ハッシュの一部だと知っています。 より複雑な入れ子を作成するために、入力名の最初の部分(上記例では person[address] )を明示的に指定することが出来ます。 <%= fields_for 'person[address][primary]', address, :index => address do |address_form| %> <%= address_form.text_field :city %> <% end %> は、このような入力を作ります。 <input id="person_address_primary_1_city" name="person[address][primary][1][city]" size="30" type="text" value="bologna" /> 一般的なルールとして、最終的な入力名は fields_for/form_for に渡された名前と index の値と属性の name を連結したものです。 ショートカットとして name[] を追加して、 :index オプションを省くことが出来ます。 <%= fields_for 'person[address][primary][]', address do |address_form| %> <%= address_form.text_field :city %> <% end %> 前の例とまったく同じ出力を生成します。 8 複雑なフォームの構築(Building Complex Forms) †多くのアプリケーションは、1つのオブジェクトを編集する単純なフォームを超えて成長します。
9 Changelog †
10 Authors †
コメント欄(誤訳・誤字があれば教えて頂ければ幸いです。) † |