【devise】デフォルトの味気ないflashメッセージにBootstrapを適用〜未解決の謎が一つ〜


本日の謎はこちら

先日実装した内容だが新規投稿時やユーザー情報編集時、または失敗時などにヘッダーの下にflashメッセージを表示している。
それぞれのアクションが成功した時or失敗した時でメッセージを変え、表示の色も変える設定をコントローラーに記述してうまくいった。

  • 成功時(色はdark)

  • 失敗時(色はdanger)

結合テストコードでログインできるかどうかをチェックしていると画面に一瞬おかしなflashメッセージが現れた。

Eメールまたはパスワードが違います。
こいつはいったいどこから来ているのか検索をかけるとエラーメッセージを日本語化しているファイルから呼び出されている。
最初はCSSで個別に当てようかと思ったが、alertそのものにかけると既存でかかっているものにも影響してしまうと気付き、別の方法を探すことに。
そこでdeviseのflashメッセージそのものにBootstrapを当てれば解決するのではないかと思い調べて解決した。

1・deviseのhelperメソッドを定義

app/helpers/devise_helper.rb

module DeviseHelper
  def bootstrap_alert(key)
    case key
    when "alert"
      "danger"
    when "notice"
      "dark"
    when "error"
      "danger"
    end
  end
end

"alert"はログイン成功時などに表示
"notice"は投稿成功時などに表示
"error"はエラーが出た時に表示
Bootstrapの公式で色がたくさん解説されているので詳しくはそちらを見てください。

2・views/layouts/_flashes.html.erbファイルを変更

views/layouts/_flashes.html.erb

<% flash.each do |key, value| %>
  <div class="alert alert-<%= bootstrap_alert(key) %> alert-dismissible fade show">
    <span><%= value %></span>
    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
      <span aria-hidden="true">&times;</span>
    </button>
  </div>
<% end %>



これで変更された。

念のためコントローラーで定義しているほうも確認してみると・・・

赤くなってたのが白くなっちゃった!なんでやねーん。
コントローラーには以下の記述。

reviews_controller.rb
  def create
    @review = Review.new(review_params)
    if @review.save
      redirect_to party_path(@review.party), dark: 'レビューの投稿ができました'
    else
      @party = Party.find(params[:party_id])
      @reviews = @party.reviews.includes(:user)
      flash[:danger] = 'レビューの投稿ができませんでした'
      render "parties/show"
    end
  end

app/helpers/devise_helper.rbで定義した中にdarkとかdangerがないからだと気付いた。
darkとかdangerになるように、 "notice"と "error"に書き換えればいいのかな?

reviews_controller.rb
  def create
    @review = Review.new(review_params)
    if @review.save
      redirect_to party_path(@review.party), notice: 'レビューの投稿ができました'  ⬅️変更
    else
      @party = Party.find(params[:party_id])
      @reviews = @party.reviews.includes(:user)
      flash[:error] = 'レビューの投稿ができませんでした'  ⬅️変更
      render "parties/show"
    end
  end

これでOK!
続いてeditアクション、updateアクション、destroyアクションにもflashメッセージを設定していたのでそちらも変更。
するとここで問題が発生。

editアクション、destroyアクションのflashメッセージがおかしい

reviews_controller.rb

  def edit
    unless current_user.id == @review.user_id
      redirect_to root_path, error: '無効なURLです'  ⬅️ここを変更した
    end
  end

  def destroy
    @review.destroy
    redirect_to party_path(@review.party), error: 'レビューの削除ができました'  ⬅️ここを変更した
  end

同じ記述方法にしているのになぜかメッセージが表示されない。
何がいけないのかよくわからないが、記述を変更したら表示された。

reviews_controller.rb
  def edit
    unless current_user.id == @review.user_id
      redirect_to root_path
      flash[:error] = '無効なURLです'
    end
  end

  def destroy
    @review.destroy
    redirect_to party_path(@review.party)
    flash[:error] = 'レビューの削除ができました'
  end

エラー

error: 'レビューの削除ができました'

OK

flash[:error] = 'レビューの削除ができました'

何が違うのだろうか?
flashを入れないと読み込んでくれていないならcreateアクションのほうで読み込まれているのがおかしい。
同じredirect_toを使っているし原因はほかのところにあるのかもしれない。
とりあえず理想とする表示にはなった。
原因がわかるかたがいらっしゃったらコメントなど頂けると幸いです。

参考にさせて頂きました

@fujimorichihiro
deviseのflashメッセージにbootstrapのアラートを適用

ありがとうございました。

追記2/17

editアクションもdestroyアクションも、alert: '無効なURLです''
この書き方でいけた。
色々試してみたが、どうやらerror:がうまく表示されないようだ。
サーバー再起動すれ直る初歩的なやつかと思って試してみたが効果はなし。
error:はダメだがalert:はOKというのがよくわからない。
深まる謎。

reviews_controller.rb
  def edit
    unless current_user.id == @review.user_id
      redirect_to root_path, alert: '無効なURLです'  ⬅️これでOK
    end
  end

    def destroy
    @review.destroy
    redirect_to party_path(@review.party), error: 'レビューの削除ができました'  ⬅️error:は表示されない
  end