フラッシュメッセージまとめ
flashのキー
flashオブジェクトはハッシュ形式で保存されており、デフォルトではnoticeとalertがキーとして設定されている。
Bootstrapを使用することで、noticeやalert以外にもsuccess(緑)
,info(青)
,warning(黄)
,danger(赤)
といったキーを使うことができる。
これらを使う場合にはflashのキーを新たに追加する宣言が必要になるため、所定の場所に記載すること。
application_controller.rb
(宣言)
class ApplicationController < ActionController::Base add_flash_types :success, :info, :warning, :danger end
複数のビューファイルで使うため、部分テンプレにしておくと便利。
layouts/_flash.html.erb
<% flash.each do |key, value| %> <p class="alert alert-<%= key %>"> <%= value %> </p> <% end %>
コントローラ
def create if user.save redirect_to root_path, success: "ユーザー登録に成功しました" else …
content_tagメソッド
↑と比べてタグを簡潔に書くことができるメソッド
<% flash.each do |key, value| %> <%= content_tag(:p, value, class: "alert alert-#{key}") %> # <%= content_tag(:タグ名, "表示する文字", class: "クラス名") %> <% end %>
redirect_toとrenderのメッセージ表示タイミング
両者の違いは処理がもう一度同じコントローラを通過するかどうか。
flashメッセージはアクションが実行されたとき、次のアクションが実行されるまで保存される。次にアクションが実行されるときに削除される仕組み。
redirect_to
一度アクションが実行されてからビューが表示される。
saveが成功した場合、遷移先のパスへ飛び、遷移先を表示するアクションが実行される。
①アクション実行 最初のアクション実行時のみflashメッセージが表示される
②flashメッセージが保存され表示
③アクション実行 2回目のアクション実行時にflashメッセージは削除される
④flashメッセージが削除
render
renderメソッドでは、saveに失敗した場合に同じcreateアクション内で定義された値をnew.html.erbに渡すことになる。
renderはアクションを通さずに、ビューファイルをレンダリングするため、次にアクションが動いたタイミングでflashメッセージが表示されてしまう。
renderは表示された後、最初のアクションが実行される。
↑これを知らなかった。勘違いして覚えていた😰
①renderでflashメッセージを表示(1回目)
②topリンクを踏むとindexアクションが実行される
③アクションが実行されたため、flashメッセージが表示(2回目)
④新規登録のリンクを踏むと、usersのnewアクションが実行
⑤2回目のアクションが実行されたため、flashメッセージが消える
↑の様な形で、変なタイミングでflashメッセージが出てきてしまう。
else flash[:danger] = "ユーザー登録に失敗しました" render :new end
↑この様に書くのは❌
このため、flash.nowを使用する
flash.nowを使うと、
①flashメッセージが保存され表示 ②アクションの実行 ③flashメッセージが削除
コントローラ
def create if user.save redirect_to root_path, success: "ユーザー登録に成功しました" else flash.now[:danger] = "ユーザー登録に失敗しました" render :new end end
flashとflash.now
flash
次のアクションが動いた後のビューファイルにflashメッセージを表示するときに使う。
flash.now
現在のアクションで表示するビューファイルのみ有効なflashメッセージを表示させる時、renderで表示させたいときに使う。
他にも・・・
flash.keepやflash.discardなどあったけど、今回は割愛。 以下サイト参考に 【Rails】 完全保存版!flashの使い方とbootstrapで表示する方法
フラッシュメッセージにi18nを当てる
以前ビューごとの翻訳を定義する際はlazy lookupを用いて下記の様に記述していた。
ja: users: new: title: '新規登録' to_login_page: 'ログインページへ'
コントローラの翻訳を定義する場合も同じように書いてOK
config/locales/views/ja.ymlファイル
ja: users: new: (省略) create: success: 'ユーザー登録に成功しました' fail: 'ユーザーできませんでした'
コントローラ
def create @user = User.new(user_params) if user.save redirect_to root_path, success: (t'.success')
プチ豆知識
redirect_back_or_to root_path, success: 'ログインしました'
rederect_back_or_toの場合、add_flash_typesで宣言していなくてもflashの記載を省略できてしまうらしい😳
通常は
redirect_to root_path, flash: { success: 'ログインしました' }
参考にしたサイト
redirect_to使った時にBootstrap対応のフラッシュメッセージを表示させる - Qiita
【Rails】 完全保存版!flashの使い方とbootstrapで表示する方法
過去課題に重複箇所あり okmt-aya-26.hatenablog.com