概要
フォームとのパラメーターのやりとりのみを確認する。
- 既存のビューにフォーム関係のタグを書き、新たなアクションに送信する
- 既存のコントローラーにそのアクションを追加し、フォームからのデータをパラメータとして受け取る
- 受け取ったパラメーターをフォームを書いた既存のビューに渡してレンダリング
- フォーム関連のタグをヘルパーに置き換える
元になる枠組み
- プロジェクト:demo_app
- コントローラー:demo_contents
- アクション:top_page
- ビュー:top_page.html.erb
STEP-1~form_tag
ビューファイルへのフォームの記述
top_page.html.erbに以下の内容を記述。
1 2 3 4 5 |
<h1>メモパッド</h1> <%= form_tag("/demo_contents/post_memo") do %> <input type="text" name="memo" placeholder="メモを入力" value=""> <input type="submit" value="書き込み"> <% end %> |
上記のform_tagは、submitされた内容を指定したアクションにpostするformタグを生成する。
ただし直接formタグを書くと”invalid authenticity token”エラーになる。
コントローラーにアクション追加
フォームからPOSTで送られる内容を受けるアクションを、コントローラにメソッドとして追加する。
1 2 3 4 5 6 7 |
class DemoContentsController < ApplicationController def top_page end def post_memo end end |
ルーティングの追加
config/routes.rbファイルに、POSTに対するアクションメソッドへのルーティングを追加する。
1 2 3 4 |
Rails.application.routes.draw do root to: 'demo_contents#top_page' post 'demo_contents/post_memo', to: 'demo_contents#post_memo' end |
アクションの確認
ルートページにフォームが表示され、テキストボックスにメモを入力して送信ボタンを押すと、Railsサーバーにデータが送られている様子が表示される。
1 2 3 4 5 6 |
Started POST "/demo_contents/post_memo" for 10.0.2.2 at 2021-03-01 22:28:24 +0900 Cannot render console from 10.0.2.2! Allowed networks: 127.0.0.0/127.255.255.255, ::1 Processing by DemoContentsController#post_memo as HTML Parameters: {"authenticity_token"=>"[FILTERED]", "memo"=>"メモ"} No template found for DemoContentsController#post_memo, rendering head :no_content Completed 204 No Content in 5ms (Allocations: 1537) |
STEP-2~params
params変数の確認
- フォームからsubmitされたときのフォーム要素の値は、
params
変数に格納される params
変数はハッシュで、フォーム要素のname
属性で指定した内容がキーになる
確認のため、demo_contents
コントローラーのpost_memo
アクションに1行追加する。
1 2 3 4 5 6 7 8 |
class DemoContentsController < ApplicationController def top_page end def post_memo puts params[:memo] end end |
ここでテキストボックスにメモを入力して送信すると、Railsサーバーにその内容が表示される。
1 2 3 4 5 6 7 |
Started POST "/demo_contents/post_memo" for 10.0.2.2 at 2021-03-01 22:46:37 +0900 Cannot render console from 10.0.2.2! Allowed networks: 127.0.0.0/127.255.255.255, ::1 Processing by DemoContentsController#post_memo as HTML Parameters: {"authenticity_token"=>"[FILTERED]", "memo"=>"メモ"} メモ No template found for DemoContentsController#post_memo, rendering head :no_content Completed 204 No Content in 1ms (Allocations: 329) |
params変数のHTMLへの反映
上記のpost_memo
アクションの内容を以下の様に変更する。
- viewから参照可能な
@memo
にフォームから受け取ったparams[:memo]
の内容をセット - トップページへのレンダリングとreturn
@変数はクラスのインスタンス変数で、これをアクションとビューで共有できる。
1 2 3 4 5 6 7 8 9 10 |
class DemoContentsController < ApplicationController def top_page @memo = "" end def post_memo @memo = params[:memo] render "demo_contents/top_page" and return end end |
またビューファイルtop_page.html.erbに以下の様に追記する。コントローラーでセットされた@memo
の内容をHTMLで表示させている。
1 2 3 4 5 6 7 8 |
<h1>メモパッド</h1> <%= form_tag("/demo_contents/post_memo") do %> <input type="text" name="memo" placeholder="メモを入力" value=""> <input type="submit" value="書き込み"> <% end %> <h2>メモの内容</h2> <p><%= @memo %></p> |
この結果、送信ボタンを押すと入力したメモの内容がtop_pageに表示されるようになる。
STEP-3~フォームヘルパー
フォーム内の要素を、以下の様にフォームヘルパー関数に書き換える。
さらにformヘルパーはhiddenタイプのinputタグを追加するが、これはCSRF対策のため。
1 2 3 4 5 6 7 8 9 |
<h1>メモパッド</h1> <%= form_tag("/demo_contents/post_memo") do %> <%= label_tag(:memo, "メモ:") %> <%= text_field_tag(:memo, nil, placeholder: "メモの内容") %> <%= submit_tag("書き込み") %> <% end %> <h2>メモの内容</h2> <p><%= @memo %></p> |
上記のlabel_tag
、text_field_tag
、submit_tag
はそれぞれ対応するタグに変換される~フォームヘルパー(旧)。
1 2 3 4 5 6 7 8 9 10 11 |
<%= label_tag(:memo, "メモ:") %> ↓ <label for="memo">メモ:</label> <%= text_field_tag(:memo, nil, placeholder: "メモの内容") %> ↓ <input id="memo" name="memo" type="text" placeholder="メモの内容"> <%= submit_tag("書き込み") %> ↓ <input name="commit" type="submit" value="書き込み" /> |
form_tagヘルパーのまとめ
フォーム全体
- form_tag…endヘルパーでフォーム全体を囲む
- form_tagではポスト先のURLを指定する
- ポスト先のURLはroutes.rbでポスト先アクションにルーティングしておく
1 2 3 |
<%= form_tag("URL") do %> ..... <% end %> |
フォーム内のヘルパー
- label、inputタグに置き換えられるヘルパーの多くは、第1引数にname属性に対応する引数をとる
- この名前引数には、一般にシンボルがあてられる
1 2 3 4 5 |
label_tag(:user_name, "入力してください") text_field_tag(:user_name) ↓ <label for="user_name">入力してください</label> <input type="text" id="user_name" name="name> |
受信側での扱い
- 受信側ではparamsというハッシュにフォームからの受信結果が入れられる
- 受信のためにルーティングされたアクション内で、このparamsを参照する
- paramsのキーに、フォームでname属性に指定したシンボルを使って値を読み出す
1 2 3 4 5 6 7 |
class DemoContentsController < ApplicationController ..... def post_process puts params[:user_name] end end |