Webアプリケーションのフォームは、ユーザー入力で多用されるインターフェイスです。しかしフォームのマークアップは、フォームのコントロールの命名法や大量の属性を扱わなければならず、作成もメンテナンスも退屈な作業になりがちです。そこでRailsでは、フォームのマークアップを生成するビューヘルパーを提供することで作業をシンプルにしています。このガイドは、さまざまなヘルパーメソッドや、利用する時期を理解するのに役立ちます。
このガイドの内容:
authenticity_token
を設定する方法このガイドはフォームヘルパーとその引数について網羅的に説明するものではありません。完全なリファレンスについては[RailsのヘルパーAPIドキュメント][]を参照してください。
最も基本的なフォームヘルパーはform_with
です。
<%= form_with do |form| %> Form contents <% end %>
上のようにform_with
を引数なしで呼び出すと、<form>
タグが生成されます。このフォームは、method
属性の値がpost
に設定され、action
属性の値が現在のページに設定されます。このフォームを現在のページに送信するときにHTTP POSTメソッドが使われます。たとえば現在のページが/home
ページだとすると、以下のようなHTMLが生成されます。
<form action="/home" accept-charset="UTF-8" method="post"> <input type="hidden" name="authenticity_token" value="Lz6ILqUEs2CGdDa-oz38TqcqQORavGnbGkG0CQA8zc8peOps-K7sHgFSTPSkBx89pQxh3p5zPIkjoOTiA_UWbQ" autocomplete="off">
このフォームに含まれているinput
要素では、type
属性がhidden
になっていることにご注目ください。GET以外のフォームを送信する場合は、このauthenticity_token
の隠し入力が必要です。
このトークンは、クロスサイトリクエストフォージェリ(CSRF)攻撃を防ぐために使われるRailsのセキュリティ機能であり、フォームヘルパーは、セキュリティ機能が有効になっていることを前提として、GET以外のすべてのフォームでこのトークンを自動的に生成します。詳しくは、Rails アプリケーションのセキュリティ保護ガイドを参照してください。
検索フォームはWebでよく使われています。検索フォームには以下のものが含まれています。
form_with
で検索フォームを作成するには、以下のように書きます。
<%= form_with url: "/search", method: :get do |form| %> <%= form.label :query, "Search for:" %> <%= form.search_field :query %> <%= form.submit "Search" %> <% end %>
上のコードから以下のHTMLが生成されます。
<form action="/search" accept-charset="UTF-8" method="get"> <label for="query">Search for:</label> <input type="search" name="query" id="query"> <input type="submit" name="commit" value="Search" data-disable-with="Search"> </form>
この検索フォームでは、form_with
のurl
オプションが使われていることにご注目ください。url: "/search"
を設定すると、フォームのaction
の値がデフォルトの現在のページのパスからaction="/search"
に変更されます。
一般に、form_with
にurl: my_path
を渡すと、リクエストを送信する場所がフォームで指定されます。別のオプションとして、Active Modelオブジェクトをフォームに渡す方法も使えます。これについては、モデルオブジェクトを指定してフォームを作成するで後述します。URLヘルパーを利用することも可能です。
上記の検索フォームの例では、FormBuilder
オブジェクトも示されています。次のセクションでは、フォームビルダーオブジェクトが提供する多くのヘルパー(form.label
やform.text_field
など)について学習します。
TIPS: フォームのあらゆるinput
要素に対して、その名前(上記の例では"query"
)からid
属性が生成されます。これらのIDは、CSSスタイル設定やJavaScriptによるフォームコントロールの操作で非常に有用です。
検索フォームには"GET"メソッドを使ってください。Railsでは基本的に、常にアクションに対応する適切なHTTPメソッド(verb)を選ぶことが推奨されています(訳注: セキュリティガイドにも記載されているように、たとえば更新フォームでGETメソッドを使うと重大なセキュリティホールが生じる可能性があります)。検索フォームで"GET"メソッドを使うと、ユーザーが特定の検索をブックマークできるようになります。
form_with
で生成されるフォームビルダーオブジェクトには、「テキストフィールド」「チェックボックス」「ラジオボタン」などの一般的なフォーム要素を生成するためのヘルパーメソッドが多数用意されています。
これらのメソッドの第1引数は、常に入力の名前です。フォームが送信されると、この名前がフォームデータとともにparams
ハッシュでコントローラに渡されるので、覚えておくと便利です。この名前は、そのフィールドにユーザーが入力した値のparams
のキーになります。
たとえば、フォームに<%= form.text_field :query %>
が含まれている場合、コントローラでparams[:query]
と書くことでこのフィールドの値を取得できます。
Railsでは、input
に名前を与えるときに特定の規約を利用します。これにより、配列やハッシュのような「非スカラー値」のパラメータをフォームから送信できるようになり、コントローラでもparams
にアクセス可能になります。これらの命名規約について詳しくは、本ガイドで後述する「フォーム入力の命名規約とparams
ハッシュ」を参照してください。これらのヘルパーの具体的な利用法について詳しくはAPIドキュメントのActionView::Helpers::FormTagHelper
を参照してください。
チェックボックスはフォームコントロールの一種で、ユーザーが選択肢の項目をオン/オフできるようにします。チェックボックスのグループは、通常、グループから1つ以上のオプションをユーザーが選択可能にしたいときに使われます。
3つのチェックボックスがあるフォームの例を以下に示します。
<%= form.checkbox :biography %> <%= form.label :biography, "Biography" %> <%= form.checkbox :romance %> <%= form.label :romance, "Romance" %> <%= form.checkbox :mystery %> <%= form.label :mystery, "Mystery" %>
上のコードによって以下が生成されます。
<input name="biography" type="hidden" value="0" autocomplete="off"><input type="checkbox" value="1" name="biography" id="biography"> <label for="biography">Biography</label> <input name="romance" type="hidden" value="0" autocomplete="off"><input type="checkbox" value="1" name="romance" id="romance"> <label for="romance">Romance</label> <input name="mystery" type="hidden" value="0" autocomplete="off"><input type="checkbox" value="1" name="mystery" id="mystery"> <label for="mystery">Mystery</label>
checkbox
の第1パラメータname
は、params
ハッシュで見つかる入力の名前です。ユーザーが「Biography」チェックボックスのみをチェックした場合、params
ハッシュには次の内容が含まれます。
{ "biography" => "1", "romance" => "0", "mystery" => "0" }
params[:biography]
で、ユーザーがそのチェックボックスを選択しているかどうかを確認できます。
チェックボックスの値(params
に表示される値)は、オプションでchecked_value
パラメータとunchecked_value
パラメータで指定できます。詳しくは、APIドキュメントのcheckbox
を参照してください。
また、collection_checkboxes
も利用できます。これについてはコレクション関連のヘルパーセクションで学習できます。
ラジオボタンは、リストから1個の項目だけを選択できるフォームコントロールです。
たとえば、以下のラジオボタンではアイスクリームの好みのフレーバーを選択できます。
<%= form.radio_button :flavor, "chocolate_chip" %> <%= form.label :flavor_chocolate_chip, "Chocolate Chip" %> <%= form.radio_button :flavor, "vanilla" %> <%= form.label :flavor_vanilla, "Vanilla" %> <%= form.radio_button :flavor, "hazelnut" %> <%= form.label :flavor_hazelnut, "Hazelnut" %>
出力されるHTMLは以下のようになります。
<input type="radio" value="chocolate_chip" name="flavor" id="flavor_chocolate_chip"> <label for="flavor_chocolate_chip">Chocolate Chip</label> <input type="radio" value="vanilla" name="flavor" id="flavor_vanilla"> <label for="flavor_vanilla">Vanilla</label> <input type="radio" value="hazelnut" name="flavor" id="flavor_hazelnut"> <label for="flavor_hazelnut">Hazelnut</label>
radio_button
の第2パラメータは、inputの値(value
)です。2つのラジオボタン項目は同じ名前(flavor
)を共有しているので、ユーザーは一方の値だけを選択できます。これにより、params[:flavor]
の値は"chocolate_chip"
、"vanilla"
、hazelnut
のいずれかになります。
チェックボックスやラジオボタンには必ずラベルも表示しておきましょう。ラベルのfor
属性でオプションとラベル名を関連付けておけば、ラベルの部分もクリック可能になるのでユーザーにとって使いやすくなります。
これまで紹介した他にも、テキスト用、メールアドレス用、パスワード用、日付時刻用など、多くのフォームコントロールを利用できます。以下の例では、これらのヘルパーの利用例と生成されるHTMLを示します。
日付時刻関連のヘルパー:
<%= form.date_field :born_on %> <%= form.time_field :started_at %> <%= form.datetime_local_field :graduation_day %> <%= form.month_field :birthday_month %> <%= form.week_field :birthday_week %>
上の出力は以下のようになります。
<input type="date" name="born_on" id="born_on"> <input type="time" name="started_at" id="started_at"> <input type="datetime-local" name="graduation_day" id="graduation_day"> <input type="month" name="birthday_month" id="birthday_month"> <input type="week" name="birthday_week" id="birthday_week">
特殊フォーマット用ヘルパー:
<%= form.password_field :password %> <%= form.email_field :address %> <%= form.telephone_field :phone %> <%= form.url_field :homepage %>
上の出力は以下のようになります。
<input type="password" name="password" id="password"> <input type="email" name="address" id="address"> <input type="tel" name="phone" id="phone"> <input type="url" name="homepage" id="homepage">
その他のよく使われるヘルパー:
<%= form.textarea :message, size: "70x5" %> <%= form.hidden_field :parent_id, value: "foo" %> <%= form.number_field :price, in: 1.0..20.0, step: 0.5 %> <%= form.range_field :discount, in: 1..100 %> <%= form.search_field :name %> <%= form.color_field :favorite_color %>
上の出力は以下のようになります。
<textarea name="message" id="message" cols="70" rows="5"></textarea> <input value="foo" autocomplete="off" type="hidden" name="parent_id" id="parent_id"> <input step="0.5" min="1.0" max="20.0" type="number" name="price" id="price"> <input min="1" max="100" type="range" name="discount" id="discount"> <input type="search" name="name" id="name"> <input value="#000000" type="color" name="favorite_color" id="favorite_color">
隠し属性(type="hidden"
)付きのinput
はユーザーには表示されませんが、テキスト入力を保持します。隠しフィールドに含まれている値はJavaScriptで変更される可能性があります。
パスワード入力フィールドを使っている場合は、利用目的にかかわらず、入力されたパスワードをRailsのログに残さないようにしておきましょう。方法についてはセキュリティガイドを参照してください。
form_with
ヘルパーの:model
オプションを使うと、フォームビルダーオブジェクトをモデルオブジェクトに紐付けできるようになります。つまり、フォームはそのモデルオブジェクトを対象とし、そのモデルオブジェクトの値がフォームのフィールドに自動入力されるようになります。
たとえば、以下のような@book
というモデルオブジェクトがあるとします。
@book = Book.find(42) # => #<Book id: 42, title: "Walden", author: "Henry David Thoreau">
新しいbookを作成するフォームは以下のようになります。
<%= form_with model: @book do |form| %> <div> <%= form.label :title %> <%= form.text_field :title %> </div> <div> <%= form.label :author %> <%= form.text_field :author %> </div> <%= form.submit %> <% end %>
HTML出力は以下のようになります。
<form action="/books" accept-charset="UTF-8" method="post"> <input type="hidden" name="authenticity_token" value="ChwHeyegcpAFDdBvXvDuvbfW7yCA3e8gvhyieai7DhG28C3akh-dyuv-IBittsjPrIjETlQQvQJ91T77QQ8xWA" autocomplete="off"> <div> <label for="book_title">Title</label> <input type="text" name="book[title]" id="book_title"> </div> <div> <label for="book_author">Author</label> <input type="text" name="book[author]" id="book_author"> </div> <input type="submit" name="commit" value="Create Book" data-disable-with="Create Book"> </form>
form_with
でモデルオブジェクトを使うと以下のような重要な処理が自動的に行われます。
action
属性には適切な値action="/books"
が自動的に入力されます。書籍を更新する場合はaction="/books/42"
のようになります。book[...]
でスコープ化されます。つまり、params[:book]
はこれらのフィールドの値をすべて含むハッシュになります。入力名の重要性について詳しくは、本ガイドのフォーム入力の命名規約とparams
ハッシュの章を参照してください。通常、フォーム入力にはモデル属性が反映されますが、必ずしもそうである必要はありません。モデル属性以外にも必要な情報がある場合は、フォームにフィールドを含めておけば、params[:book][:my_non_attribute_input]
のようにアクセスできます。
モデルで複合主キー(composite primary key)が使われている場合は、同じフォームビルダー構文から得られる出力が少し異なります。
複合主キー[:author_id, :id]
を持つ@book
モデルオブジェクトの場合を例にします。
@book = Book.find([2, 25]) # => #<Book id: 25, title: "Some book", author_id: 2>
以下のフォームを作成します。
<%= form_with model: @book do |form| %> <%= form.text_field :title %> <%= form.submit %> <% end %>
上のコードから以下のHTML出力が生成されます。
<form action="/books/2_25" method="post" accept-charset="UTF-8" > <input name="authenticity_token" type="hidden" value="ChwHeyegcpAFDdBvXvDuvbfW7yCA3e8gvhyieai7DhG28C3akh-dyuv-IBittsjPrIjETlQQvQJ91T77QQ8xWA" /> <input type="text" name="book[title]" id="book_title" value="Some book" /> <input type="submit" name="commit" value="Update Book" data-disable-with="Update Book"> </form>
生成されたURLには、author_id
とid
の値が2_25
のようにアンダースコア区切りの形で含まれていることにご注目ください。送信後、コントローラーはパラメータから個別の主キーの値を抽出して、単一の主キーと同様にレコードを更新できます。
fields_for
ヘルパーfields_for
ヘルパーは、同じフォーム内の関連モデルオブジェクトのフィールドをレンダリングするのに使われます。通常、関連付けられている「内部の」モデルはActive Recordの関連付けを介して「メインの」フォームモデルに関連付けられます。たとえば、関連付けられているContactDetail
モデルを持つPerson
モデルがある場合、以下のように両方のモデルの入力を含む単一のフォームを作成できます。
<%= form_with model: @person do |person_form| %> <%= person_form.text_field :name %> <%= fields_for :contact_detail, @person.contact_detail do |contact_detail_form| %> <%= contact_detail_form.text_field :phone_number %> <% end %> <% end %>
上のコードから以下のHTML出力が得られます。
<form action="/people" accept-charset="UTF-8" method="post"> <input type="hidden" name="authenticity_token" value="..." autocomplete="off" /> <input type="text" name="person[name]" id="person_name" /> <input type="text" name="contact_detail[phone_number]" id="contact_detail_phone_number" /> </form>
fields_for
で生成されるオブジェクトは、form_with
で生成されるのと同様のフォームビルダーです。
fields_for
ヘルパーは同様のバインディングを作成しますが、<form>
タグはレンダリングされません。field_for
について詳しくは、APIドキュメントを参照してください。
RESTfulなリソースを扱っている場合、レコード識別(record identification)を使うとform_with
の呼び出しがはるかに簡単になります。これは、モデルのインスタンスを渡すだけで、後はRailsがそこからモデル名など必要な情報を取り出して処理してくれるというものです。以下の例では、長いバージョンと短いバージョンのどちらを使っても同じ出力を得られます。
# 長いバージョン: form_with(model: @article, url: articles_path) # 短いバージョン(レコード識別を利用): form_with(model: @article)
同様に、以下のように既存の記事を編集する場合、form_with
の長いバージョンと短いバージョンのどちらを使っても同じ出力を得られます。
# 長いバージョン: form_with(model: @article, url: article_path(@article), method: "patch") # 短いバージョン(レコード識別を利用): form_with(model: @article)
短い方のform_with
呼び出し構文は、レコードの作成・編集のどちらでもまったく同じである点が便利です。レコード識別では、レコードが新しいかどうかをrecord.persisted?
で自動的に識別します。さらに送信用の正しいパスを選択し、オブジェクトのクラスに基づいた名前も選択してくれます。
これは、ルーティングファイルでArticle
モデルがresources :articles
で宣言されていることを前提としています。
単数形リソースを使う場合は、form_with
が機能するために以下のようにresource
とresolve
を呼び出す必要があります。
resource :article resolve("Article") { [:article] }
リソースを宣言すると、いくつかの副作用があります。リソースの設定や利用方法について詳しくは、ルーティングガイドを参照してください。
モデルで単一テーブル継承(STI: single-table inheritance)を使っている場合、親クラスがリソースを宣言されていてもサブクラスでレコード識別を利用できません。その場合は:url
と:scope
(モデル名)を明示的に指定する必要があります。
名前空間付きのルーティングがある場合、form_with
でそのためのショートカットを利用できます。たとえば、アプリケーションにadmin
名前空間がある場合は、以下のように書けます。
form_with model: [:admin, @article]
上のコードはそれによって、admin名前空間内にあるArticlesController
に送信するフォームを作成します。つまり、更新の場合はadmin_article_path(@article)
に送信します。
名前空間のレベルが増えた場合も、同様の構文で書けます。
form_with model: [:admin, :management, @article]
Railsのルーティングシステムおよび関連するルールについて詳しくはルーティングガイドを参照してください。
RailsフレームワークはRESTfulな設計を推奨しています。つまり、アプリケーション内のフォームはGET
とPOST
の他に、method
がPATCH
、PUT
、またはDELETE
であるリクエストを作成します。しかし、HTMLフォーム自体は、フォームの送信に関してGET
とPOST
以外のHTTPメソッドをサポートしていません。
そこでRailsでは、これらのメソッドをPOST
メソッド上でエミュレートする形でこの制約を回避しています。具体的には、フォームのHTMLに"_method"
という名前の隠し入力を追加し、使いたいHTTPメソッドをここで指定します。
form_with(url: search_path, method: "patch")
上のコードから以下のHTML出力が得られます。
<form action="/search" accept-charset="UTF-8" method="post"> <input type="hidden" name="_method" value="patch" autocomplete="off"> <input type="hidden" name="authenticity_token" value="R4quRuXQAq75TyWpSf8AwRyLt-R1uMtPP1dHTTWJE5zbukiaY8poSTXxq3Z7uAjXfPHiKQDsWE1i2_-h0HSktQ" autocomplete="off"> <!-- ... --> </form>
Railsは、POST
されたデータを解析する際にこの特殊な_method
パラメータをチェックし、リクエストのHTTPメソッドが_method
の値として指定されているもの(この場合はPATCH
)であるかのように振る舞います。
formmethod:
キーワードを指定すると、フォームをレンダリングするときに送信ボタンが指定のmethod
属性をオーバーライドできるようになります。
<%= form_with url: "/posts/1", method: :patch do |form| %> <%= form.button "Delete", formmethod: :delete, data: { confirm: "Are you sure?" } %> <%= form.button "Update" %> <% end %>
<form>
要素の場合と同様、ほとんどのブラウザはformmethod
で宣言されるGET
とPOST
以外のフォームメソッドをサポートしていません。
Railsでは、POST
メソッド上でこれらのメソッドをエミュレートする形でこの問題を回避しています。具体的には、formmethod
、value
、name
属性を組み合わせることでエミュレートします。
<form accept-charset="UTF-8" action="/posts/1" method="post"> <input name="_method" type="hidden" value="patch" /> <input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" /> <!-- ... --> <button type="submit" formmethod="post" name="_method" value="delete" data-confirm="Are you sure?">Delete</button> <button type="submit" name="button">Update</button> </form>
上の場合、「Update」ボタンはPATCH
メソッドとして扱われ、「Delete」ボタンはDELETE
メソッドとして扱われます。
セレクトボックス(ドロップダウンリストとも呼ばれます)を使うと、ユーザーがオプションリストから項目を選択できるようになります。セレクトボックスのHTMLには、選択するオプションごとに1個の<option>
要素を書かなければならないので、かなりの量のマークアップが必要になります。Railsには、このマークアップを生成するヘルパーメソッドが用意されています。
たとえば、ユーザーに選択して欲しい都市名のリストがあるとします。select
ヘルパーを使うと以下のようにセレクトボックスを作成できます。
<%= form.select :city, ["Berlin", "Chicago", "Madrid"] %>
上のコードで以下のHTMLが出力されます。
<select name="city" id="city"> <option value="Berlin">Berlin</option> <option value="Chicago">Chicago</option> <option value="Madrid">Madrid</option> </select>
選択の結果は、他のパラメータと同様にparams[:city]
で取得できます。
セレクトボックスのラベル(表示名)と異なる<option>
値を指定することも可能です。
<%= form.select :city, [["Berlin", "BE"], ["Chicago", "CHI"], ["Madrid", "MD"]] %>
上のコードで以下のHTMLが出力されます。
<select name="city" id="city"> <option value="BE">Berlin</option> <option value="CHI">Chicago</option> <option value="MD">Madrid</option> </select>
こうすることで、ユーザーには完全な都市名が表示されますが、params[:city]
は"BE"
、"CHI"
、"MD"
のいずれかの値になります。
最後に、:selected
引数を使うとセレクトボックスのデフォルト値も指定できます。
<%= form.select :city, [["Berlin", "BE"], ["Chicago", "CHI"], ["Madrid", "MD"]], selected: "CHI" %>
上のコードで以下のHTMLが出力されます。
<select name="city" id="city"> <option value="BE">Berlin</option> <option value="CHI" selected="selected">Chicago</option> <option value="MD">Madrid</option> </select>
場合によっては、関連するオプションをグループ化してユーザーエクスペリエンスを向上させたいことがあります。これは、以下のようにselect
にHash
(または同等のArray
)を渡すことで行なえます。
<%= form.select :city, { "Europe" => [ ["Berlin", "BE"], ["Madrid", "MD"] ], "North America" => [ ["Chicago", "CHI"] ], }, selected: "CHI" %>
上のコードで以下のHTMLが出力されます。
<select name="city" id="city"> <optgroup label="Europe"> <option value="BE">Berlin</option> <option value="MD">Madrid</option> </optgroup> <optgroup label="North America"> <option value="CHI" selected="selected">Chicago</option> </optgroup> </select>
セレクトボックスも、他のフォームコントロールと同様にモデル属性に紐づけ可能です。たとえば、以下の@person
というモデルオブジェクトがあるとします。
@person = Person.new(city: "MD")
以下はそのフォームです。
<%= form_with model: @person do |form| %> <%= form.select :city, [["Berlin", "BE"], ["Chicago", "CHI"], ["Madrid", "MD"]] %> <% end %>
セレクトボックスのHTML出力は以下のようになります。
<select name="person[city]" id="person_city"> <option value="BE">Berlin</option> <option value="CHI">Chicago</option> <option value="MD" selected="selected">Madrid</option> </select>
唯一の違いは、選択されたオプションがparams[:city]
ではなくparams[:person][:city]
にあることです。
selected="selected"
が適切なオプションに自動的に追加されている点にご注目ください。このセレクトボックスはモデルに紐付けられているので、:selected
引数を指定する必要はありません。
前述したdate_field
ヘルパーやtime_field
ヘルパーに加えて、Railsはプレーンなセレクトボックスをレンダリングする日付および時刻の代替フォームヘルパーも提供します。date_select
ヘルパーは、年/月/日などの一時コンポーネントごとにセレクトボックスをレンダリングします。
たとえば、以下のような@person
というモデルオブジェクトがあるとします。
@person = Person.new(birth_date: Date.new(1995, 12, 21))
以下はそのフォームです。
<%= form_with model: @person do |form| %> <%= form.date_select :birth_date %> <% end %>
セレクトボックスのHTML出力は以下のようになります。
<select name="person[birth_date(1i)]" id="person_birth_date_1i"> <option value="1990">1990</option> <option value="1991">1991</option> <option value="1992">1992</option> <option value="1993">1993</option> <option value="1994">1994</option> <option value="1995" selected="selected">1995</option> <option value="1996">1996</option> <option value="1997">1997</option> <option value="1998">1998</option> <option value="1999">1999</option> <option value="2000">2000</option> </select> <select name="person[birth_date(2i)]" id="person_birth_date_2i"> <option value="1">January</option> <option value="2">February</option> <option value="3">March</option> <option value="4">April</option> <option value="5">May</option> <option value="6">June</option> <option value="7">July</option> <option value="8">August</option> <option value="9">September</option> <option value="10">October</option> <option value="11">November</option> <option value="12" selected="selected">December</option> </select> <select name="person[birth_date(3i)]" id="person_birth_date_3i"> <option value="1">1</option> ... <option value="21" selected="selected">21</option> ... <option value="31">31</option> </select>
フォームが送信されたときのparams
ハッシュには、完全な日付を含む単一の値が存在しない点にご注目ください。代わりに、"birth_date(1i)"
のような特殊な名前を持つ複数の値が存在します。しかしActive Modelは、モデル属性の宣言された型に基づいて、これらの特殊な名前を持つ値を完全な日付や時刻として組み立てる方法を知っています。つまり、フォームで完全な日付を表す1個のフィールドを使う場合と同じように、params[:person]
をPerson.new
やPerson#update
などに渡せるということです。
Railsでは、date_select
ヘルパーの他に、time_select
ヘルパー(時や分のセレクトボックスを出力する)やdatetime_select
ヘルパー(日付と時刻のセレクトボックスの組み合わせ)も提供しています。
Railsでは、個別の日付時刻コンポーネント向けのセレクトボックスをレンダリングするヘルパーとしてselect_year
、select_month
、select_day
、select_hour
、select_minute
、select_second
も提供しています。
これらのヘルパーは「素の」メソッドなので、フォームビルダーのインスタンスでは呼び出されません。たとえば以下のようにselect_year
ヘルパーを使うとします。
<%= select_year 2024, prefix: "party" %>
セレクトボックスのHTML出力は以下のようになります。
<select id="party_year" name="party[year]"> <option value="2019">2019</option> <option value="2020">2020</option> <option value="2021">2021</option> <option value="2022">2022</option> <option value="2023">2023</option> <option value="2024" selected="selected">2024</option> <option value="2025">2025</option> <option value="2026">2026</option> <option value="2027">2027</option> <option value="2028">2028</option> <option value="2029">2029</option> </select>
各ヘルパーでは、デフォルト値として数値ではなくDate
オブジェクトやTime
オブジェクトを指定できます(たとえば、上記の代わりに<%= select_year Date.today, prefix: "party" %>
)。ここから適切な日付と時刻の部分が抽出されて使われます。
ユーザーにどのタイムゾーンにいるのかを尋ねる必要がある場合は、非常に便利なtime_zone_select
ヘルパーが使えます。
通常は、ユーザーが選択可能なタイムゾーンオプションのリストを提供する必要があります。定義済みのActiveSupport::TimeZone
オブジェクトのリストがなければ作業が面倒になる可能性があります。time_with_zone
ヘルパーはこのリストをラップしているので、次のように書けます。
<%= form.time_zone_select :time_zone %>
上のコードから、以下のHTMLが出力されます。
<select name="time_zone" id="time_zone"> <option value="International Date Line West">(GMT-12:00) International Date Line West</option> <option value="American Samoa">(GMT-11:00) American Samoa</option> <option value="Midway Island">(GMT-11:00) Midway Island</option> <option value="Hawaii">(GMT-10:00) Hawaii</option> <option value="Alaska">(GMT-09:00) Alaska</option> ... <option value="Samoa">(GMT+13:00) Samoa</option> <option value="Tokelau Is.">(GMT+13:00) Tokelau Is.</option> </select>
Railsで任意のオブジェクトのコレクションから選択肢のセットを生成する必要がある場合は、collection_select
、collection_radio_button
、およびcollection_checkboxes
ヘルパーが利用できます。
これらのヘルパーの有用さを示すために、City
モデルと、それに対応するPerson
モデルとの間にbelongs_to :city
関連付けがある場合を考えます。
class City < ApplicationRecord end class Person < ApplicationRecord belongs_to :city end
データベースには以下の都市名が保存されているとします。
City.order(:name).map { |city| [city.name, city.id] } # => [["Berlin", 1], ["Chicago", 3], ["Madrid", 2]]
これで、ユーザーは以下のようなフォームで都市名をデータベースから選択できるようになります。
<%= form_with model: @person do |form| %> <%= form.select :city_id, City.order(:name).map { |city| [city.name, city.id] } %> <% end %>
上のコードから、以下のHTMLが出力されます。
<select name="person[city_id]" id="person_city_id"> <option value="1">Berlin</option> <option value="3">Chicago</option> <option value="2">Madrid</option> </select>
上のコード例は、選択肢を手動で生成する方法を示していますが、Railsには明示的に反復処理を書かずにコレクションから選択肢を生成するヘルパーがあります。これらのヘルパーは、コレクション内の各オブジェクトで指定のメソッドを呼び出すことによって、各選択肢の値とテキストラベルを決定します。
belongs_to
関連付けのフィールドをレンダリングするときは、関連付け自体の名前ではなく、外部キー名(上の例ではcity_id
)を指定しなければなりません。
collection_select
ヘルパーcollection_select
ヘルパーを使えば、以下のように都市名を選択するセレクトボックスを生成できます。
<%= form.collection_select :city_id, City.order(:name), :id, :name %>
セレクトボックスのHTML出力は以下のように手書きの場合と同じになります。
<select name="person[city_id]" id="person_city_id"> <option value="1">Berlin</option> <option value="3">Chicago</option> <option value="2">Madrid</option> </select>
引数の順序は、collection_select
の場合とselect
の場合で異なっていることにご注意ください。collection_select
では、第1引数に値のメソッド(上の例では:id
)、第2引数にテキストラベルのメソッド(上の例では:name
)を指定します。select
ヘルパーで選択肢を指定する場合の引数の順序はこれと逆である点にご注意ください(テキストラベルが最初で次が値)。前述のコード例では["Berlin", 1]
となります。
collection_radio_buttons
ヘルパーラジオボタンのセットを生成するには、collection_radio_buttons
ヘルパーを使います。
<%= form.collection_radio_buttons :city_id, City.order(:name), :id, :name %>
ラジオボタンのHTML出力は以下のようになります。
<input type="radio" value="1" name="person[city_id]" id="person_city_id_1"> <label for="person_city_id_1">Berlin</label> <input type="radio" value="3" name="person[city_id]" id="person_city_id_3"> <label for="person_city_id_3">Chicago</label> <input type="radio" value="2" name="person[city_id]" id="person_city_id_2"> <label for="person_city_id_2">Madrid</label>
collection_checkboxes
ヘルパーたとえばhas_and_belongs_to_many
関連付けをサポートする形でチェックボックスのセットを生成するには、collection_checkboxes
ヘルパーを使います。
<%= form.collection_checkboxes :interest_ids, Interest.order(:name), :id, :name %>
チェックボックスのHTML出力は以下のようになります。
<input type="checkbox" name="person[interest_id][]" value="3" id="person_interest_id_3"> <label for="person_interest_id_3">Engineering</label> <input type="checkbox" name="person[interest_id][]" value="4" id="person_interest_id_4"> <label for="person_interest_id_4">Math</label> <input type="checkbox" name="person[interest_id][]" value="1" id="person_interest_id_1"> <label for="person_interest_id_1">Science</label> <input type="checkbox" name="person[interest_id][]" value="2" id="person_interest_id_2"> <label for="person_interest_id_2">Technology</label>
訳注:
collection_check_boxes
はcollection_checkboxes
にリネームされました。従来のcollection_check_boxes
はエイリアスとして残されていますが、新しいコードではcollection_checkboxes
を使う方が良いでしょう。
ファイルのアップロードはフォームでよく行われるタスクの1つです(アバター画像のアップロードや、処理したいCSVファイルのアップロードなど)。file_field
ヘルパーを使えば、以下のようにファイルアップロード用フィールドをレンダリングできます。
<%= form_with model: @person do |form| %> <%= form.file_field :csv_file %> <% end %>
ファイルアップロードで忘れてはならない重要な点は、レンダリングされるフォームのenctype
属性を必ずmultipart/form-data
に設定しておかなければならない点です。これは、以下のようにform_with
の内側でfile_field_tag
ヘルパーを使えば自動で行われます。enctype
属性は手動でも設定できます。
<%= form_with url: "/uploads", multipart: true do |form| %> <%= file_field_tag :csv_file %> <% end %>
どちらの場合も、出力されるHTMLフォームは以下のようになります。
<form enctype="multipart/form-data" action="/people" accept-charset="UTF-8" method="post"> <!-- ... --> </form>
なお、form_with
の規約によって、上述の2つのフィールド名が異なっている点にご注意ください。つまり前者のフォームではフィールド名がperson[csv_file]
になり(params[:person][:csv_file]
でアクセス可能)、後者のフォームでは単なるcsv_file
になります(params[:csv_file]
でアクセス可能)。
file_field
を使う場合、params
ハッシュ内のオブジェクトはActionDispatch::Http::UploadedFile
のインスタンスです。アップロードされたCSVファイルのデータをアプリケーションのレコードに保存する方法の例を次に示します。
require "csv" def upload uploaded_file = params[:csv_file] if uploaded_file.present? csv_data = CSV.parse(uploaded_file.read, headers: true) csv_data.each do |row| # CSVファイルを1行ずつ処理する # SomeInvoiceModel.create(amount: row['Amount'], status: row['Status']) Rails.logger.info row.inspect #<CSV::Row "id":"po_1KE3FRDSYPMwkcNz9SFKuaYd" "Amount":"96.22" "Created (UTC)":"2022-01-04 02:59" "Arrival Date (UTC)":"2022-01-05 00:00" "Status":"paid"> end end # ... end
ファイルをモデルと一緒に保存する必要がある画像(ユーザーのプロフィール写真など)である場合、ファイルの保存場所(ディスク、Amazon S3など)、画像ファイルのサイズ変更、サムネイルの生成など、考慮すべきタスクがいくつかあります。Active Storageは、このようなタスクを支援するように設計されています。
form_with
やfields_for
によって生成されるオブジェクトは、フォームビルダーと呼ばれます。フォームビルダーはActionView::Helpers::FormBuilder
のインスタンスであり、フォームビルダーを使うことで、モデル要素に関連付けられているフォーム要素を生成できます。このクラスは、アプリケーションにカスタムヘルパーを追加する形で拡張可能です。
たとえば、アプリケーション全体でtext_field
とlabel
を表示する場合は、以下のヘルパーメソッドをapplication_helper.rb
に追加できます。
module ApplicationHelper def text_field_with_label(form, attribute) form.label(attribute) + form.text_field(attribute) end end
以下のように、このヘルパーを通常通りにフォーム内で利用します。
<%= form_with model: @person do |form| %> <%= text_field_with_label form, :first_name %> <% end %>
ただし、ActionView::Helpers::FormBuilder
のサブクラスを作成し、そこにヘルパーを追加することも可能です。このLabellingFormBuilder
サブクラスを以下のように定義します。
class LabellingFormBuilder < ActionView::Helpers::FormBuilder def text_field(attribute, options = {}) # superは元のtext_fieldメソッドを呼び出す label(attribute) + super end end
先ほどのフォームは以下で置き換え可能です。
<%= form_with model: @person, builder: LabellingFormBuilder do |form| %> <%= form.text_field :first_name %> <% end %>
このクラスを頻繁に再利用する場合は、以下のようにlabeled_form_with
ヘルパーを定義してbuilder: LabellingFormBuilder
オプションを自動的に適用してもよいでしょう。
module ApplicationHelper def labeled_form_with(**options, &block) options[:builder] = LabellingFormBuilder form_with(**options, &block) end end
form_with
の代わりに以下の書き方も可能です。
<%= labeled_form_with model: @person do |form| %> <%= form.text_field :first_name %> <% end %>
上記の3つのケース(text_field_with_label
ヘルパー、LabellingFormBuilder
サブクラス、およびlabeled_form_with
ヘルパー)は、いずれも以下のように同じHTML出力を生成します。
<form action="/people" accept-charset="UTF-8" method="post"> <!-- ... --> <label for="person_first_name">First name</label> <input type="text" name="person[first_name]" id="person_first_name"> </form>
ここで使われているフォームビルダーは、以下のコードが実行された時の動作も決定します。
<%= render partial: f %>
f
がActionView::Helpers::FormBuilder
のインスタンスである場合、このコードはform
パーシャルを生成し、そのパーシャルオブジェクトをフォームビルダーに設定します。このフォームビルダーのクラスがLabellingFormBuilder
の場合、代わりにlabelling_form
パーシャルがレンダリングされます。
LabellingFormBuilder
などのフォームビルダーのカスタマイズでは、実装の詳細が隠蔽されます(上記の単純な例ではやり過ぎのように思えるかもしれません)。フォームでカスタム要素をどの程度頻繁に利用するかに応じて、FormBuilder
クラスを拡張するか、ヘルパーを作成するかなど、さまざまなカスタマイズから選択することになります。
params
ハッシュこれまで説明したフォームヘルパーはすべて、ユーザーがさまざまなタイプの入力を行えるフォーム要素のHTMLを生成するのに役立ちます。ユーザー入力値にコントローラー側でアクセスするにはどうすればよいでしょうか。その答えがparams
ハッシュです。params
ハッシュについては、上記の例で既に確認しました。このセクションでは、フォーム入力がparams
ハッシュでどのように構造化されるかという命名規約について、より具体的に説明します。
params
ハッシュには、配列や、ハッシュの配列を含めることが可能です。値は、params
ハッシュの最上位レベルに置くことも、別のハッシュにネストすることも可能です。たとえば、Personモデルの標準のcreate
アクションでは、params[:person]
はPerson
オブジェクトのすべての属性のハッシュになります。
HTMLフォーム自体にはユーザー入力データに対する固有の構造が定められておらず、生成されるのは名前と値の文字列のペアだけであることにご注意ください。アプリケーションで使われる配列やハッシュは、Railsで利用するパラメータ命名規約による結果です。
params
ハッシュ内のフィールドは、コントローラで許可しておく必要があります。
ユーザー入力フォームデータの基本的な2つの構造は、配列とハッシュです。
ハッシュには、params
の値にアクセスするための構文が反映されます。たとえば、フォームに次の内容が含まれている場合は以下のようになります。
<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" } } }
もう1つの構造は配列です。通常、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]
は送信された電話番号の配列になります。
{ "person" => { "phone_number" => ["555-0123", "555-0124", "555-0125"] } }
これら2つの概念は、組み合わせて使うことも可能です。ハッシュの要素の1つは、値が配列である可能性があります。前述の例では、params[:person]
ハッシュには[:phone_number]
というキーがあり、その値は配列です。
ハッシュの配列も利用できます。たとえば、フォームで以下のコード片を繰り返すことで、任意の個数の住所を作成できます。
<input name="person[addresses][][line1]" type="text"/> <input name="person[addresses][][line2]" type="text"/> <input name="person[addresses][][city]" type="text"/> <input name="person[addresses][][line1]" type="text"/> <input name="person[addresses][][line2]" type="text"/> <input name="person[addresses][][city]" type="text"/>
これにより、ハッシュの配列params[:person][:addresses]
が得られます。配列内の各ハッシュには、次のようなキーline1
、line2
、およびcity
が含まれます。
{ "person" => { "addresses" => [ { "line1" => "1000 Fifth Avenue", "line2" => "", "city" => "New York" }, { "line1" => "Calle de Ruiz de Alarcón", "line2" => "", "city" => "Madrid" } ] } }
ここで重要なのは、ハッシュはいくらでもネストできますが、配列は1階層しか使えない点に注意することです。配列はたいていの場合ハッシュで置き換えられます。たとえば、モデルオブジェクトの配列の代わりに、モデルオブジェクトのハッシュを使えます。このキーではid、配列インデックスなどのパラメータが利用できます。
配列パラメータは、checkbox
ヘルパーとの相性がよくありません。HTMLの仕様では、オンになっていないチェックボックスからは値が送信されません。しかし、チェックボックスからは常に値が送信される方が何かと便利です。そこでcheckbox
ヘルパーでは、同じ名前で予備の隠し入力を作成しておき、本来送信されないはずのチェックボックス値が見かけ上送信されるようになっています。チェックボックスがオフになっていると隠し入力値だけが送信され、チェックボックスがオンになっていると本来のチェックボックス値と隠し入力値が両方送信されますが、このとき優先されるのは本来のチェックボックス値の方です。この隠しフィールドを省略したい場合は、include_hidden
オプションをfalse
に設定できます(デフォルトではtrue
)。
たとえば、各個人の住所に対応するフィールドのセットを持つフォームをレンダリングしたいとします。こんなときはfields_for
ヘルパーと、ハッシュの添字を指定する:index
オプションが便利です。
<%= form_with model: @person do |person_form| %> <%= person_form.text_field :name %> <% @person.addresses.each do |address| %> <%= person_form.fields_for address, index: address.id do |address_form| %> <%= address_form.text_field :city %> <% end %> <% end %> <% end %>
この個人が2つの住所を持っていて、idがそれぞれ23と45だとすると、上のフォームから以下のようなHTMLが出力されます。
<form accept-charset="UTF-8" action="/people/1" method="post"> <input name="_method" type="hidden" value="patch" /> <input id="person_name" name="person[name]" type="text" /> <input id="person_address_23_city" name="person[address][23][city]" type="text" /> <input id="person_address_45_city" name="person[address][45][city]" type="text" /> </form>
このときのparams
ハッシュは以下のようになります。
{ "person" => { "name" => "Bob", "address" => { "23" => { "city" => "Paris" }, "45" => { "city" => "London" } } } }
フォームビルダーのperson_form
でfields_for
を呼び出したので、フォームのすべてのinputは"person"
ハッシュに対応付けられます。また、index: address.id
を指定することで、各都市のinputのname
属性をperson[address][city]
ではなくperson[address][#{address.id}][city]
としてレンダリングしています。このように、params
ハッシュを処理する際に、どのAddressレコードを変更すべきかを決定可能になります。
fields_for
で添字を利用するindex
オプションについて詳しくは、APIドキュメントを参照してください。
アプリケーションが大きくなるにつれて、単一オブジェクトの編集を超える複雑なフォームを作成しなければならなくなる場合があります。たとえば、Person
を作成するときに、ユーザーが同じフォーム内に複数のAddress
レコード(自宅、職場など)を作成できます。後でユーザーがPerson
レコードを編集するときに、住所を追加・削除・更新できるようにしておく必要もあります。
特定のモデル(この場合はPerson
)に関連付けられているレコードを編集するために、Active Recordはaccepts_nested_attributes_for
メソッドを介したモデルレベルのサポートを提供します。
class Person < ApplicationRecord has_many :addresses, inverse_of: :person accepts_nested_attributes_for :addresses end class Address < ApplicationRecord belongs_to :person end
上のコードによってaddresses_attributes=
メソッドがPerson
モデル上に作成され、これを用いて住所の作成、更新、および削除を行なえます。
ユーザーは以下のフォームを用いてPerson
とそれに関連する複数の住所を作成できます。
<%= form_with model: @person do |form| %> Addresses: <ul> <%= form.fields_for :addresses do |addresses_form| %> <li> <%= addresses_form.label :kind %> <%= addresses_form.text_field :kind %> <%= addresses_form.label :street %> <%= addresses_form.text_field :street %> ... </li> <% end %> </ul> <% end %>
関連付けにネステッド属性が渡されると、fields_for
ヘルパーは関連付けの要素ごとにブロックを1回ずつレンダリングします。特に、Person
に住所が登録されていない場合は何もレンダリングされません。
フィールドのセットが1個以上ユーザーに表示されるように、コントローラで1つ以上の空白の子要素を作成しておくというのはよく行われるパターンです。以下の例では、新しいPersonフォームに2組みの住所フィールドがレンダリングされます。
たとえば、上記のform_with
に以下の変更を加えたとします。
def new @person = Person.new 2.times { @person.addresses.build } end
上のコードによって以下のHTMLが出力されます。
<form action="/people" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="lWTbg-4_5i4rNe6ygRFowjDfTj7uf-6UPFQnsL7H9U9Fe2GGUho5PuOxfcohgm2Z-By3veuXwcwDIl-MLdwFRg" autocomplete="off"> Addresses: <ul> <li> <label for="person_addresses_attributes_0_kind">Kind</label> <input type="text" name="person[addresses_attributes][0][kind]" id="person_addresses_attributes_0_kind"> <label for="person_addresses_attributes_0_street">Street</label> <input type="text" name="person[addresses_attributes][0][street]" id="person_addresses_attributes_0_street"> ... </li> <li> <label for="person_addresses_attributes_1_kind">Kind</label> <input type="text" name="person[addresses_attributes][1][kind]" id="person_addresses_attributes_1_kind"> <label for="person_addresses_attributes_1_street">Street</label> <input type="text" name="person[addresses_attributes][1][street]" id="person_addresses_attributes_1_street"> ... </li> </ul> </form>
fields_for
ヘルパーはフォームフィールドを1つ生成します。accepts_nested_attributes_for
ヘルパーが受け取るのはこのようなパラメータの名前です。たとえば、2つの住所を持つユーザーを1人作成する場合、送信されるparams
内のパラメータは以下のようになります。
{ "person" => { "name" => "John Doe", "addresses_attributes" => { "0" => { "kind" => "Home", "street" => "221b Baker Street" }, "1" => { "kind" => "Office", "street" => "31 Spooner Street" } } } }
この:address_attributes
ハッシュのキーの実際の値は重要ではありませんが、アドレスごとに異なる整数の文字列である必要があります。
関連付けられたオブジェクトが既に保存されている場合、fields_for
メソッドは、保存されたレコードのid
を持つ隠し入力を自動生成します。fields_for
にinclude_id: false
を渡すことでこの自動生成をオフにできます。
{ "person" => { "name" => "John Doe", "addresses_attributes" => { "0" => { "id" => 1, "kind" => "Home", "street" => "221b Baker Street" }, "1" => { "id" => "2", "kind" => "Office", "street" => "31 Spooner Street" } } } }
コントローラ内でパラメータをモデルに渡す前に、いつもと同様にコントローラ内でパラメータの許可リストチェックを宣言する必要があります。
def create @person = Person.new(person_params) # ... end private def person_params params.expect(person: [ :name, addresses_attributes: [[ :id, :kind, :street ]] ]) end
accepts_nested_attributes_for
にallow_destroy: true
を渡すと、関連付けられているオブジェクトをユーザーが削除することを許可できます。
class Person < ApplicationRecord has_many :addresses accepts_nested_attributes_for :addresses, allow_destroy: true end
あるオブジェクトの属性のハッシュに、キーが_destroy
で、値がtrue
と評価可能(1
、'1'
、true
、'true'
など)な組み合わせがあると、そのオブジェクトは破棄されます。以下のフォームではユーザーが住所を削除可能です。
<%= form_with model: @person do |form| %> Addresses: <ul> <%= form.fields_for :addresses do |addresses_form| %> <li> <%= addresses_form.checkbox :_destroy %> <%= addresses_form.label :kind %> <%= addresses_form.text_field :kind %> ... </li> <% end %> </ul> <% end %>
_destroy
フィールドのHTMLは以下のようになります。
<input type="checkbox" value="1" name="person[addresses_attributes][0][_destroy]" id="person_addresses_attributes_0__destroy">
このとき、コントローラ内でパラメータの許可リストを以下のように更新して、_destroy
フィールドが必ずパラメータに含まれるようにしておく必要もあります。
def person_params params.require(:person). permit(:name, addresses_attributes: [:id, :kind, :street, :_destroy]) end
ユーザーが何も入力しなかったフィールドを無視できれば何かと便利です。これは、:reject_if
procをaccepts_nested_attributes_for
に渡すことで制御できます。このprocは、フォームから送信された属性にあるハッシュごとに呼び出されます。このprocがtrue
を返す場合、Active Recordはそのハッシュに関連付けられたオブジェクトを作成しません。以下の例では、kind
属性が設定されている場合にのみ住所オブジェクトを生成します。
class Person < ApplicationRecord has_many :addresses accepts_nested_attributes_for :addresses, reject_if: lambda { |attributes| attributes["kind"].blank? } end
代わりにシンボル:all_blank
を渡すこともできます。このシンボルが渡されると、_destroy
の値を除くすべての属性が空白レコードを受け付けなくなるprocが1つ生成されます。
外部リソースに何らかのデータを渡す必要がある場合も、Railsのフォームヘルパーを用いてフォームを作成する方がやはり便利です。外部APIに対してauthenticity_token
を設定することが期待されている場合は、以下のようにform_with
にauthenticity_token: '外部トークン'
パラメータを渡すことで実現できます。
<%= form_with url: "http://farfar.away/form", authenticity_token: "external_token" do %> Form contents <% end %>
場合によっては、フォームで利用可能なフィールドが外部APIによって制限されていて、authenticity_token
隠しフィールドを生成すると不都合が生じることがあります。トークンを送信しないようにするには、以下のように:authenticity_token
オプションにfalse
を渡します。
<%= form_with url: "http://farfar.away/form", authenticity_token: false do %> Form contents <% end %>
フォームのフィールドをフォームビルダーのコンテキストの外でレンダリングする必要が生じたときのために、よく使われるフォーム要素を生成するタグヘルパーを提供しています。たとえば、checkbox_tag
は以下のように使えます。
<%= checkbox_tag "accept" %>
上のコードから以下のHTMLが生成されます。
<input type="checkbox" name="accept" id="accept" value="1" />
一般に、これらのヘルパー名は、フォームビルダーのヘルパー名の末尾に_tag
を追加したものになります。完全なリストについては、FormTagHelper
APIドキュメントを参照してください。
form_tag
やform_for
の利用についてRails 5.1でform_with
が導入されるまでは、form_with
の機能はform_tag
とform_for
に分かれていました。form_tag
およびform_for
は、禁止ではないものの、利用は推奨されていません。現在はform_with
の利用が推奨されています。
Railsガイドは GitHub の yasslab/railsguides.jp で管理・公開されております。本ガイドを読んで気になる文章や間違ったコードを見かけたら、気軽に Pull Request を出して頂けると嬉しいです。Pull Request の送り方については GitHub の README をご参照ください。
原著における間違いを見つけたら『Rails のドキュメントに貢献する』を参考にしながらぜひ Rails コミュニティに貢献してみてください 🛠💨✨
本ガイドの品質向上に向けて、皆さまのご協力が得られれば嬉しいです。
Railsガイド運営チーム (@RailsGuidesJP)
Railsガイドは下記の協賛企業から継続的な支援を受けています。支援・協賛にご興味あれば協賛プランからお問い合わせいただけると嬉しいです。