Bootstrapでflashメッセージを実装
概要
以下のflashメッセージをbootstrapで表示させる。
- ログイン成功時・・・「ログインしました」
- ログイン失敗時・・・「ログインに失敗しました」
- ログアウト時・・・「ログアウトしました」
- ユーザー登録時・・・「ユーザー登録が完了しました」
- ユーザー登録失敗時・・・「ユーザー登録に失敗しました」
定義の追加
flashオブジェクトはハッシュ形式で保存されており、viewにメッセージを表示している。デフォルトではnoticeとalertキーしかない。bootstrapを使用する場合、下図のようなキーが使用できる。
これらのキーを使用するにはキーを許可する宣言をしなければならない。
application_controller.rbに以下の記述をする。
add_flash_types :success, :info, :warning, :danger
すると、success, :info, :warning, :dangerのキーが使用可能になる。
flashメッセージの表示をviewに追加
flashメッセージは複数のviewで使用するのでパーシャルを使う。
_flash_message.html.erbを作成しapplication_controllerで読み込む。
<% flash.each do |key, value| %> <div class="alert alert-<%= key %>"><%= value %></div> <% end %>
keyとvalueはコントローラーから指定する。
例1
redirect_back_or_to root_path, success: 'ログインしました'
「success」がkeyで「ログインしました」はvalueで取得される。
例2
flash.now[:danger] = 'ログインに失敗しました'
「danger」がkeyで「ログインに失敗しました」がvalue
flashとflash.nowの違い
flash[:danger]の場合は次のアクションまでメッセージを表示させる。 flash.now[:danger]とすると、次のアクションに遷移した時点でメッセージが消える。
パーシャルを読み込む
#... <body> <% if logged_in? %> <%= render 'shared/header'%> <% else %> <%= render 'shared/before_login_header'%> <% end %> <%= render 'shared/flash_message'%> <%= yield %> <%= render 'shared/footer'%> </body> </html>
ログイン・ログアウト時にflashメッセージを表示させる
ログイン成功、ログアウト時はsuccessキーで表示。 ログイン失敗時はdangerキーで表示させる。
class UserSessionsController < ApplicationController skip_before_action :require_login, only: %i[create new] def new; end def create @user = login(params[:email], params[:password]) if @user redirect_back_or_to root_path, success: 'ログインしました' else flash.now[:danger] = 'ログインに失敗しました' render :new end end def destroy logout redirect_to root_path, danger: 'ログアウトしました' end end
renderとredirect_toの違い
上記を例とすると、
ログインできた場合
users#createアクション→root_path(users#index)→index.html.erbが描画される。
ログインに失敗した場合
users#createアクション→new.html.erbが描画される。という処理が流れる。
この処理から、redirect_to は、view の表示には直接は関係なく、新たな HTTPリクエストが発行される。*GETのみ(下図参照)
renderはcreateアクションに指定した値を直接表示させることがわかる。
ユーザー登録時にflashメッセージを表示させる。
ユーザー登録に成功したときと失敗したときに、メッセージを表示させる。
#... def create @user = User.new(user_params) if @user.save redirect_to login_path, success: 'ユーザー登録が完了しました' else flash.now[:danger] = 'ユーザー登録に失敗しました' render :new end end #...
追記
ログイン前のヘッダーにあるログインボタンのhttpリクエストをgetにする。 ここがpostとかになっているとヘッダーのログインボタンからログインページにいったときにflashメッセージが表示されてしまう。
<%= link_to 'ログインする', login_path, method: :get, class: 'nav-link' %>
link_toメソッド
Railsでは主にviewファイルで使用され、引数を指定することでリンクを生成する。 <%= link_to 'リンクの文言', 'パス', class: 'クラス名', method: :HTTPリクエスト %>
methodでリンク先のルーティングを指定できる。