更新日:
【Rails】 完全保存版!flashの使い方とbootstrapで表示する方法
flashとは、ユーザーに対してページ遷移した時に簡単なメッセージを一時的に表示させる機能です。
例えば、ユーザー登録が完了した時とか、失敗した時にメッセージを表示させてあげるとユーザーにとって優しいですよね。
検証で保存されなかった時なども、どういう原因で保存が失敗したかなどメッセージで教えてあげるとより親切です。そんな時に使うのがflashメッセージです。
上の例だと「名前を入力してください」がflashメッセージです。
常時表示されるわけではなく、一時的に表示されるメッセージとなります。
flashの使い方
この章では、flashの基本的な使い方から応用的な使い方まで解説します。
flashの基本的な書き方
flashはハッシュのような形式で記述します。
1
flash[:キー名] = "表示させたいメッセージ"
上のキー名は自分の好きな名前をつけることができます。
フラッシュメッセージを表示させたい箇所に下記のように記述します。
1
<%= flash[:キー名] %>
具体的には下記のように記述します。
1
2
3
4
5
6
# 例
if article.save
flash[:notice] = "登録が完了しました。"
redirect_to root_path
else
~ 略 ~
1
<%= flash[:notice] %>
ビューファイルで上のコードを書いた箇所にflashメッセージが表示されます。
noticeとalertオプション
キーには好きな名前をつけられますが、あらかじめnotice
とalert
はオプションが用意されています。
この2つは下記のように使用が可能です。
1
2
<%= notice %>
<%= alert %>
このようにflashを省略して書く事ができます。
notice
は何かの通知に、alert
は警告のメッセージという風に使い分けると良いでしょう。
flash用の部分テンプレートを作ろう
flashメッセージは複数のビューファイルで使うので、部分テンプレートにしておくと便利です。
1
2
3
4
5
<% flash.each do |key, value| %>
<p class="alert alert-<%= key %>">
<%= value %>
</p>
<% end %>
flashはハッシュのようなものなのでeachメソッド
を使うことができます。
上のように書くと「flash[:キー名] = "メッセージ"」の部分の「キー名」をkey
で、「メッセージ」をvalue
で取得できます。
このkey
とvalue
という変数名は任意で決められます。
試しに下記のコードを実行してみます。
1
flash[:alert] = "名前を入力してください"
今回はキー名にalert
を、メッセージに「名前を入力してください」と定義しました。
これを表示させるためにビューファイルに下記のように書いてみます。
1
2
3
4
<% flash.each do |key, value| %>
<p>キー名: <%= key %><p>
<p>メッセージ: <%= value %><p>
<% end %>
するとこのようにちゃんとキー名とメッセージが表示されました。
1
2
3
4
5
<% flash.each do |key, value| %>
<p class="alert alert-<%= key %>">
<%= value %>
</p>
<% end %>
先ほどの上のコードはcontent_tagメソッド
を使うと、下記のように記述することもできます。
1
2
3
<% flash.each do |key, value| %>
<%= content_tag(:p, value, class: "alert alert-#{key}") %>
<% end %>
content_tagメソッド
タグを簡潔に書くことができるメソッドです。
下記のように定義します。
1
<%= content_tag(:タグ名, "表示する文字", class: "クラス名") %>
今回はキーをメッセージが表示されるスタイルのクラス名の部分で、バリューを実際に表示される文字として使っています。
呼び出したい部分には下記のように記述しましょう。
1
<%= render partial: 'layouts/flash' %>
redirect_toの時の書き方
redirect_to
でnotice
とalert
を使う時は非常に簡潔に記述することができます。
1
2
3
4
5
6
# 例
if article.save
redirect_to root_path, notice: "表示させたいメッセージ"
else
~ 略 ~
end
他のキーの場合は下記のように記述します。
1
2
3
4
5
6
# 例
if article.save
redirect_to path, flash: {キー名: "表字させたいメッセージ"}
else
~ 略 ~
end
この場合は下記のように記述します。
1
2
3
4
5
6
# 例
if article.save
redirect_to path, flash: {success: "登録が完了しました"}
else
~ 略 ~
end
redirect_toは一度アクションが実行されてからビューが表示されます。
redirect_to
の場合は、下の図のような流れとなります。
上の流れになるので、最初のアクションが実行された後の1回のみflashメッセージが表示されます。
renderの時の書き方
flashメッセージはアクションが動いた時に表示され、次のアクションが動くと消去される仕組みになっています。
renderメソッドを使うときはアクションを通さないでビューファイルをレンダリングするため、次のアクションが動いた後にflashメッセージが表示されてしまいます。
render
の場合は表示された後、最初のアクションが実行されます。
flashメッセージは2回目のアクションが実行された時に削除されるため、2回flashメッセージが表示されてしまいます。
1
2
3
4
5
6
7
# 例
if article.save
redirect_to root_path, notice: "登録が完了しました"
else
flash[:alert] = "名前を入力してください"
render :new
end
上のコードは保存が失敗したらrenderメソッドにより同じビューがレンダリングされます。
renderメソッドを使っているので、アクションは実行されません。
そしてTOPをクリックすると、topページのindexアクションを通してルートパスが表示されるようになっています。
flashメッセージはアクションが実行された時、次のアクションが実行されるまで保存され表示されます。
次にアクションが実行される時に削除される仕組みになっています。
その為、topページのindexアクションがrender後の初めてのアクションの実行になります。
上の流れで動くのでこのようにルートパスのビューにもflashメッセージが残ってしまいました。
次にnewアクションが動くことによって表示が消えるのが確認できます。
これでは困るのでflash.now
を使用します。
flash.now
を使った場合は下の図のような流れとなります。
1
2
3
4
5
6
7
# 例
if article.save
redirect_to root_path, notice: "登録が完了しました"
else
flash.now[:alert] = "名前を入力してください"
render :new
end
flash.now
を使った時の挙動を確認してみます。
このように次のアクションが動いてもメッセージが持ち越されなくなっているのが確認できますね!
次のアクションが動くまで表示されるので、renderでビューファイルが表示される限りずっとflashメッセージは表示され続けます。
flashとflash.nowの違い
上の例のようにflash
は次のアクションが動いた後のビューファイルにflashメッセージを表示する時に、
flash.now
は現在のアクションで表示するビューファイルのみ有効なflashメッセージを表示させたい時(renderで表示させたい時)に使用します。
flash.keepの使い方
前述した通りflashメッセージはアクションが動いた時に表示され、次のアクションが動くと消去されますが、flash.keep
を使うと指定されたフラッシュを次のアクションに持ち越すことができます。
1
2
3
4
5
# 全てのflashメッセージが持ち越される
flash.keep
# 指定したキーのflashメッセージが持ち越される
flash.keep(:キー名)
1
2
3
4
5
6
7
8
9
10
11
# 例
before_action :flash_keep
# 中略
private
def flash_keep
flash.now[:alert] = "名前を入力してください"
flash.keep(:alert)
end
上のように定義するとアクションが2回実行された後もflashメッセージは残り続けます。
flash.discardの使い方
次に動くアクションまで有効なflashメッセージを、今のアクション内のみ有効なflashメッセージに変える方法があります。
それがflash.discard
です。
1
2
3
4
5
# 全てのflashメッセージを破棄する
flash.discard
# 指定したキーのflashメッセージを破棄する
flash.discard(:キー名)
下記のように使います。
1
2
3
4
5
6
7
8
# 例
if article.save
redirect_to root_path, notice: "登録が完了しました"
else
flash[:alert] = "名前を入力してください"
flash.discard(:alert)
render :new
end
上のように記述すると現在のアクション内のみ有効なflashメッセージになるのでflash.now
を使った時と同じ挙動になります。
もっとRuby on Railsを体系的に学びたい!という方は、複数人での開発体制やテストコードの書き方など実際の開発現場での役に立つこちらの参考書が良いでしょう。
flashをbootstrapで表示しよう
cssのフレームワークであるbootstrap
を使うとflashメッセージをかっこよく表示させることができます。
railsにbootstrapを導入しよう
railsにbootstrapを導入するにはGemfileにgemを追加します。
下記のコードをGemfileに追記し、bundle installコマンドを実行しましょう。
1
2
gem 'jquery-rails'
gem 'bootstrap', '~> 4.1.1'
次にapp/assets/stylesheets/application.css
の拡張子をscssに変更し、下記の一文を追記します。
1
@import "bootstrap";
bootstrapのjavascriptを対応させるために下記のコードをapp/assets/javascripts/application.js
に追記します。
1
2
3
//= require jquery3
//= require popper
//= require bootstrap-sprockets
これで準備は完了です。
flashメッセージにbootstrapのデザインを当ててみよう
では実際にbootstrapで定義されているスタイルを当ててみましょう。
bootstrapではflashメッセージ用に下記のようなスタイルが用意されています。
1
2
3
4
<タグ class="alert alert-色の指定">
# 例
<p class="alert alert-primary">
このスタイルを当てると下記のようなデザインになります。
上のコードのprimary
の部分が色を指定する箇所になります。
この部分をbootstrapで定義されているクラス名に変更することにより色を変えることができます。
上のprimary
以外にも下記の色が定義されています。
secondary
1
<p class="alert alert-secondary">
success
1
<p class="alert alert-success">
danger
1
<p class="alert alert-danger">
warning
1
<p class="alert alert-warning">
info
1
<p class="alert alert-info">
light
1
<p class="alert alert-light">
dark
1
<p class="alert alert-dark">
部分テンプレートに合わせる必要があるので、キー名に色の指定を設定しましょう。
1
2
3
4
5
6
# 例:緑色で表示させたい場合
if article.save
flash[:success] = "登録が完了しました。"
redirect_to root_path
else
~ 略 ~
こうすれば下記のkey
の部分に色を指定するsuccess
が入るので、緑色のデザインが適用されます。
1
2
3
<% flash.each do |key, value| %>
<%= content_tag(:p, value, class: key) %>
<% end %>
flashメッセージに閉じるボタンを付けよう
flashメッセージは次のアクションが動くまで消えません。
なのでflashメッセージが表示されているページで手動でflashメッセージを閉じることができる機能をつけてみましょう。
1
2
3
<div class="alert alert-danger">
<%= alert %><button type="button" class="close" data-dismiss="alert">×</button>
</div>
上のように記述するとbootstrapのjavascriptが実行され、×ボタンを押すとflashメッセージが削除されます。
今回「×」は特殊文字の&times;
で指定しています。
このように自分でflashメッセージを削除することができるようになりました!
ただし、これはbootstrapを導入していないと使えないので、導入していない場合は自分でjavascriptを作成する必要があるので注意しましょう。
このようにflashメッセージはとても便利な機能です。
ただflashメッセージはrails側で保存されるのではなく、自分のPCのCookieにデータを保存して表示させています。
Cookieが無効になっているブラウザでは表示されないので気をつけましょう。
この記事のまとめ
- flashは簡単なメッセージを1回だけ表示させる事ができる便利な機能のこと
- flashメッセージ用の部分テンプレートを作成しておくと便利!
- 同じリクエスト内でflashを使う時はflash.nowを使う