2024年11月のおすすめスクール

【Rails】Flashメッセージの使い方とメッセージの拡張・応用

  • URLをコピーしました!

何かの処理を行った時に(例えば以下のような)

・ユーザー登録に成功しました
・ログインしました
・口コミの投稿が成功しました
・写真を投稿しました
・本人確認に失敗しました

flashメッセージを使うことでメッセージを表示することができます。今日はflashメッセージの使い方と拡張・応用をしてみたのでそれを備忘録しています。

私は「写真を投稿しました」の時だけ「SNSボタンを表示してシェアしてみませんか?」みたいなこともやりたかったので、それも実装しました。

目次

まずは簡単なflashメッセージの使い方

使い方は簡単です。コントローラー側で処理を行いそれにたいして(成功とか失敗とかの)flashメッセージを作成します。ビュー側でflashメッセージを表示します。

◆コントローラー側

flash[:success] = '写真を投稿しました'
flash[:danger] = '写真の投稿に失敗しました'
flash[:notice] = 'お知らせ'
flash[:aiueo] = '文字列を入力'

こんな形です。flashメッセージはいわばハッシュなのでkeyとvalueを設定してあげる形です。

通常コントローラーからビューに変数を渡す時は変数の頭に@を付けるルールがあったと思いますが、flashメッセージには不要なようです。(railsドキュメント flashのリファレンス

◆ビュー側

以下のようにしてメッセージを表示できます。

<%= flash[:success] %>
<%= flash[:danger] %>
<%= flash[:notice] %>
<%= flash[:aiueo] %>

erbではhメソッドでHTMLエンコードも行うなら(例えば&は&amp;とか<は&lt;とか)

&amp;amp;lt;%= h(flash[:success]) %&amp;amp;gt;
&amp;amp;lt;%= h(flash[:danger]) %&amp;amp;gt;
&amp;amp;lt;%= h(flash[:notice]) %&amp;amp;gt;
&amp;amp;lt;%= h(flash[:aiueo]) %&amp;amp;gt;

こんな形になります。

もしflashメッセージにHTMLタグを使うなら以下のように使えばよいでしょう。

◆コントローラー側

<br>タグで改行してみます。

flash[:aiueo] = '明日は&amp;amp;lt;br&amp;amp;gt;晴れるかなぁ'

◆ビュー側

html_safeメソッドを使ってHTMLタグをタグとして出力してくれます。

&amp;amp;lt;%= flash[:aiueo].html_safe %&amp;amp;gt;

flashメッセージが消えないときは

先程のリファレンスを見ると、flash.nowというメソッドがあるのでそれを活用すれば良いと思います。これで今のアクションにだけ適用されます。

コントローラー側で以下のように記述。

flash.now[:abc] = 'あべし'

逆にflashメッセージの有効期限を保持するのであれば、キーと値を設定した後に以下のようにメソッドを呼び出します。

flash.keep(:abc)

flashメッセージを外部ファイルでパーシャルにすると楽

パーシャルはどのビューにも共通する部分をまとめたファイルです。アンダーバーで始まるファイル名にします。

例えば、views/layouts/_flash_messages.html.erbというファイルを作ってそこにflashメッセージの表示部分を任せます。このやり方はテックアカデミーの教材で学びました。

外部ファイルの中身を以下のようにしています。

&amp;amp;lt;% flash.each do |message_type, message| %&amp;amp;gt;
    &amp;amp;lt;div class=&amp;amp;quot;alert alert-&amp;amp;lt;%= message_type %&amp;amp;gt;&amp;amp;quot;&amp;amp;gt;
      &amp;amp;lt;%= message %&amp;amp;gt;
    &amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;% end %&amp;amp;gt;

これをビュー側でrenderメソッドを使って呼び出します。呼び出す時はディレクトリ/アンダーバーを消したファイル名(.html.erbも書かない)とします。

&amp;amp;lt;%= render 'layouts/flash_messages' %&amp;amp;gt;

flashメッセージのテクニック

もしcssでbootstrapによるデザインを使っているなら、flashメッセージのハッシュのkeyには:successや:infoや:dangerや:warningを使うことをおすすめします。(bootstrapじゃなくて自作のcssでも応用すれば良いと思います。)

bootstrapには以下の4つのcssのclassがありまして。

&amp;amp;lt;div class=&amp;amp;quot;alert alert-success&amp;amp;quot;&amp;amp;gt;成功時のメッセージカラーは緑&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;div class=&amp;amp;quot;alert alert-info&amp;amp;quot;&amp;amp;gt;通知用のメッセージカラーは青&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;div class=&amp;amp;quot;alert alert-warning&amp;amp;quot;&amp;amp;gt;警告用のメッセージカラーは黄色&amp;amp;lt;/div&amp;amp;gt;
&amp;amp;lt;div class=&amp;amp;quot;alert alert-danger&amp;amp;quot;&amp;amp;gt;危険用のメッセージカラーは赤色&amp;amp;lt;/div&amp;amp;gt;

それぞれ以下のようなイメージでメッセージ表示用の吹き出しが出ます。これを活用しているのです。

flashメッセージの表示部分のここ↓ですね。

&amp;amp;lt;% flash.each do |message_type, message| %&amp;amp;gt;
  &amp;amp;lt;div class=&amp;amp;quot;alert alert-&amp;amp;lt;%= message_type %&amp;amp;gt;&amp;amp;quot;&amp;amp;gt;

flashメッセージのハッシュのkeyはflashのeach doで、message_typeで取り出してるのでbootstrapのクラス名に合わせることで、自動的に吹き出しの色を指定してるだけなんですが。

そして以下の部分でコントローラー側で設定したメッセージを表示します。

      &amp;amp;lt;%= message %&amp;amp;gt;

成功したときにSNSボタンを表示させる

これは私自身が運営するWEBアプリで、そういう仕様にしたいと思いまして。

ユーザーによる投稿処理が成功したら、その画面でさらにSNS(FBやTwitter)にシェアをしてもらえたらな、という思いです。写真投稿に成功したときだけこのSNSボタンを表示させます。(SNSボタンを表示する方法に関しては前の記事に書いてあります。→【Rails】自作のSNSボタンを貼り付ける方法

特に難しいことはなくて。

コントローラー側では以下のように記述。

    if @photo.save  #ここで写真を保存
      flash[:photosuccess] = '写真を投稿しました!'
    else
      flash[:danger] = '写真の投稿に失敗しました'
    end

    redirect_to @shop

ビュー側(shops/show.html.erb)では以下のように記述。renderでflash_messagesを呼び出してるだけです。

  &amp;amp;lt;%= render 'layouts/flash_messages' %&amp;amp;gt;

パーシャル(layouts/flash_messages.html.erb)では以下のように記述。

&amp;amp;lt;% flash.each do |message_type, message| %&amp;amp;gt;

  &amp;amp;lt;% if flash[:photosuccess] %&amp;amp;gt;
    &amp;amp;lt;div class=&amp;amp;quot;alert alert-success&amp;amp;quot;&amp;amp;gt;
      &amp;amp;lt;%= message %&amp;amp;gt;
      &amp;amp;lt;p&amp;amp;gt;是非SNSでも当サイトをシェアしてください。&amp;amp;lt;/p&amp;amp;gt;
      &amp;amp;lt;%= render 'layouts/snsbutton' %&amp;amp;gt;
    &amp;amp;lt;/div&amp;amp;gt;
  &amp;amp;lt;% else %&amp;amp;gt;
    &amp;amp;lt;div class=&amp;amp;quot;alert alert-&amp;amp;lt;%= message_type %&amp;amp;gt;&amp;amp;quot;&amp;amp;gt;
      &amp;amp;lt;%= message %&amp;amp;gt;
    &amp;amp;lt;/div&amp;amp;gt;
  &amp;amp;lt;% end %&amp;amp;gt;
&amp;amp;lt;% end %&amp;amp;gt;

これは3行目でflash[:photosuccess]があれば、「是非SNSでも当サイトをシェアしてください。」を表示して、なおかつ次の行でrenderメソッドで外部ファイルの_snsbutton.html.erbを表示しています。(この_snsbutton.html.erbにはSNSボタンが記述されています)

ということで投稿をしてもらった時だけ以下のようなSNSへのシェアを促すflashメッセージを出すようにしました。


目次