Railsチュートリアルで使われている2種類のメッセージ表示メソッドflash[]とflash.now[]。
どちらもメッセージを表示するという結果は変わらないですが、処理によってうまく動作しなかったりするので、それぞれの使い分けついて書いていきます。
flash[]とflash.now[]
結論から言うと、下記になります。
flash[]:
redirect_to 使用時(データの追加、更新、削除を行いたいとき)
flash.now[]:
render 使用時(データの取得を行いたいとき)
なぜこのような使い分けをするかというと、次の画面を表示するためのrenderとredirect_toによって処理の仕方が異なり、その処理の違いに関連してflash[]が表示され続けてしまったり、表示されなかったりします。
なぜrenderとredirect_toをそもそもなぜ使い分けるかを、ざっくり書いていきます。
renderとredirect_to
render: ・そのままviewを出力するメソッド。再度リクエストを投げない。 ・route→controller(render)→viewredirect_to:
・再度リクエストを投げなおし、ルーティングからもう一回処理をし直す。
・route→controller(redirect_to)→route→controller→view
どちらも結果としては画面遷移のためのメソッドですが、redirect_toは再度リクエストを投げる処理をしています。
これは別の画面を呼び出したいときに、再度リクエストを投げてその画面のアクションを呼び出しなおすことで、処理の無駄をなくさせるためです。
renderは別画面を描画するだけで、別画面のアクション内の処理を実行しません。
そのため、renderで別画面の処理を正常に表示させたい場合、別画面のアクションの処理をrender前で処理したうえで、renderを実行する必要があります。
そういった、別の画面を呼び出す際に、わざわざrednderの前にその画面用の処理を書くより、その別画面用のアクションをredirect_toで呼び出してしまえば、処理を2重に書かずに済み、ラクチンです。
しかし、redirect_toでルーティングをしなおした際に、保持していたインスタンス変数がリセットされてしまいます。
そのため、
・フォームで送信失敗時に情報を残しておきたい時はrenderでフォームに値を入れる
・データ更新をして、別画面に遷移させる際はredirect_toを使う
といった使い分けになります。
このredirect_toとrenderによって、再度リクエストされてアクションが呼びだされるかが、ここでは重要です。
flashとflash.now[]の使い分け
renderとredirect_toの説明が長くなりましたが、flash[]とflash.now[]に立ち戻ります。各メソッドのflashメッセージの消失トリガーは、
flash[]
次次アクション終了時に削除
flash.now[]
次アクション終了時に削除
よって、renderやredirect_toと組み合わせた場合、(redirect_toとrender, flashとflash.nowの違いから引用)
flash[]とredirect_to => 次のページにリダイレクトした時点でflashは消える
flash[]とrender => renderはリクエストを送信しないため、次のページに移動してもflashは残る
flash.now[]とredirect_to => redirect_toの時点でflashが消えるため、flash自体表示されない
flash.now[]とrender => 次のページへリダイレクトした時点でflashは消える
となります。
したがって、遷移した一回のみ表示させたい際の適切な使い分けは、
flash[]:
redirect_to 使用時(データの追加、更新、削除を行いたいとき)
flash.now[]:
render 使用時(データの取得を行いたいとき)
nowがついているほうは「今リクエスト」だけ表示すると認識すると覚えやすいですね。
間違っていたらコメントいただけると幸いです。
参考:
Railsドキュメント 簡単なメッセージを画面に表示
renderとredirect_toの違いを整理 【Day 1/30 2nd】
redirect_toとrender, flashとflash.nowの違い
Railsガイド 2.3 redirect_toを使用する