2021年9月2日 現場Rails Chapter7(7-1-2 新規登録画面からの遷移先を変える)
form要素内のsubmitボタン
form要素内のsubmitボタンを押すと、以下の挙動が実行されます。
現場Rails P.289
form要素内のsubmitボタンが押されると、パラメータに、押されたボタンのname属性の値をキーとしてキャプションが格納されます。
例)
f.submit '戻る', name: 'back' #=> params[:back]に'戻る'という文字列が格納されて、アクションへ渡されます。 f.submit '登録' #=> params[:commit]に'登録'という文字列が格納されて、アクションへ渡されます。
※commitパラメータ とは、どのボタンが押されたのか、サーバ側で判断できるように、デフォルトでついています。そのため、name属性の値を省略しても、commitで補っているのです。
redirect_to @taskについて
redirect_toメソッドは、以下のように省略して書けます。
redirect_to task_url(@task.id) # リンクのパスとしてモデルオブジェクトが渡されると自動でidにリンクされるので、「.id」を省略出来ます。 redirect_to task_url(@task) # URLヘルパーは省略出来ます。 redirect_to (@task) # Rubyでは()は省略出来ます。 redirect_to @task
確認画面で戻るボタンを押した時、入力フォームに入れた値をどのように次の画面へ渡しているのか?(p291)
# app/views/tasks/confirm_new.html.slim = form_with model: @task, local: true do |f| table.table.table.hover tbody # フォーム入力 = f.submit '戻る', name: 'back', class: '# 省略' = f.submit '登録', class: '# 省略'
form_withの仕組み
↓画像引用:【Rails】form_with/form_forについて【入門】
フォームの"model:@task"の@taskに入った中身によってどのアクションを呼び出すのかを判断させています。上のフォームで戻るボタンを押した場合、confirm_newアクション側で定義した@taskがフォームに設定されているので、RailsがCreateアクションを呼び出す仕組みになっています。
# app/controllers/tasks_controoler.rb class TasksController < ApplicationController # 〜〜〜 省略 〜〜〜 def new @task = Task.new end def confirm_new @task = current_user.tasks.new(task_params) render :new unless @task.valid? end def create # 入力フォームの内容を元にタスクを作成後、@taskに代入 @task = current_user.tasks.new(task_params) # ============================================= # 「登録内容の確認」ページ(confirm_new.html.slim)で "戻る"を押す。 # "戻る"を押すとparams[:back]に'戻る'という文字列が入る。 # params[:back]に値が入っている場合、present?メソッドの戻り値がtrueになる。 # 最初に定義した@taskがform_withヘルパーに設定されるので、 # フォームに入力した情報がタスク新規登録画面に再度表示される。 if params[:back].present? render :new return # returnが無いと以下のコードも実行してしまう。 end # ============================================= # ********************************************* # 「登録内容の確認」ページ(confirm_new.html.slim)で"登録"を押す。 # "登録"を押したので、params[:back]は存在しない。 # そのため、上のif文が実行されずに終了する。 # 上のif文が終了後、下のif文が正常に実行されると、タスクがDBに保存される。 if @task.save redirect_to @task, notice: "タスク...登録しました。" else render :new end # ********************************************* end # 〜〜〜 省略 〜〜〜 end
↑インスタンス変数(@task)は次のビューへ情報を渡すことが出来ます。renderをすることによって、インスタンス変数の情報を渡すことが出来るのです。ここで、redirect_toをしてしまうと再度ブラウザからリクエストを出してから画面遷移をするので、インスタンス変数の情報を渡せないため、注意が必要です。
returnを書く意味
rubyではreturnを省略できるので、使い馴染みのないreturnが TasksController で使われている事に疑問を持ちました。今回の場合returnがないと次のif文である@task.save
まで処理が行われてしまいます。そしてrenderメソッドは同じアクションの中で2回以上呼び出されるとエラーになります。これを防ぐためにreturn
を書いているわけですがrender :new and return
このように and return
と書くこともできます。
render
また今回の例ではないがredirect_to
の後の処理も実行されてしまう事を覚えておくとよいでしょう。
#新規登録画面(ビュー) h1 タスク新規登録 # 省略 # @taskのところに、フォームに入力された値が入ってくる(インスタンス変数として) = form_with model: @task, local: true, url: confirm_new do |f| .form-group #省略 = f.submit'確認', class: #省略
redirect_toとrender挙動の違い
# インスタンス変数の値は次の画面に送られません。 redirect_to #=>(再度リクエストを出して)画面を遷移させます。 # インスタンス変数の値は次の画面に送られます。 render #=> 画面を遷移させます(リクエストを出さずに)
- render : controller → view
- redirect_to : controller → URL → route → controller → view
参照
redirect_to @userが何を省略しているかわかりますか?〜挫折しないRailsチュートリアル7章〜
https://qiita.com/Kawanji01/items/96fff507ed2f75403ecb
【Rails】form_with/form_forについて【入門
https://qiita.com/snskOgata/items/44d32a06045e6a52d11c
【Rails】renderとredirect_toの違いと使い分け
https://qiita.com/morikuma709/items/e9146465df2d8a094d78
Railsのutf8パラメータとcommitパラメータ
Railsのutf8パラメータとcommitパラメータ - koukiblog
pikawakaブログrenderメソッドを使うときの注意点
【Rails】 renderメソッドの使い方を徹底解説! | Pikawaka - ピカ1わかりやすいプログラミング用語サイト