すでにメンバーの場合は

無料会員登録

GitHubアカウントで登録 Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

登録がまだの方はこちらから

Pikawakaにログイン

GitHubアカウントでログイン Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

Rails

【Rails】 完全保存版!flashの使い方とbootstrapで表示する方法

ぴっかちゃん
ぴっかちゃん

flashとは、ユーザーに対してページ遷移した時に簡単なメッセージを一時的に表示させる機能です。

例えば、ユーザー登録が完了した時とか、失敗した時にメッセージを表示させてあげるとユーザーにとって優しいですよね。

検証で保存されなかった時なども、どういう原因で保存が失敗したかなどメッセージで教えてあげるとより親切です。そんな時に使うのが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が表示されている

noticeとalertオプション

キーには好きな名前をつけられますが、あらかじめnoticealertはオプションが用意されています。

この2つは下記のように使用が可能です。

ビューファイル
1
2
<%= notice %>
<%= alert %>

このようにflashを省略して書く事ができます。

noticeは何かの通知に、alertは警告のメッセージという風に使い分けると良いでしょう。

flash用の部分テンプレートを作ろう

flashメッセージは複数のビューファイルで使うので、部分テンプレートにしておくと便利です。

layouts/_flash.html.erb
1
2
3
4
5
<% flash.each do |key, value| %>
    <p class="alert alert-<%= key %>">
      <%= value %>
    </p>
<% end %>

flashはハッシュのようなものなのでeachメソッドを使うことができます。
上のように書くと「flash[:キー名] = "メッセージ"」の部分の「キー名」をkeyで、「メッセージ」をvalueで取得できます。

このkeyvalueという変数名は任意で決められます。

試しに下記のコードを実行してみます。

コントローラー
1
flash[:alert] = "名前を入力してください"

今回はキー名にalertを、メッセージに「名前を入力してください」と定義しました。
これを表示させるためにビューファイルに下記のように書いてみます。

ビューファイル
1
2
3
4
<% flash.each do |key, value| %>
  <p>キー名: <%= key %><p>
  <p>メッセージ: <%= value %><p>
<% end %>

するとこのようにちゃんとキー名とメッセージが表示されました。

flash.each

layout/_flash.html.erb
1
2
3
4
5
<% flash.each do |key, value| %>
    <p class="alert alert-<%= key %>">
      <%= value %>
    </p>
<% end %>

先ほどの上のコードはcontent_tagメソッドを使うと、下記のように記述することもできます。

layout/_flash.html.erb
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_tonoticealertを使う時は非常に簡潔に記述することができます。

コントローラー
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の場合は、下の図のような流れとなります。

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メッセージ

flashメッセージはアクションが実行された時、次のアクションが実行されるまで保存され表示されます。

次にアクションが実行される時に削除される仕組みになっています。
その為、topページのindexアクションがrender後の初めてのアクションの実行になります。

render

上の流れで動くのでこのようにルートパスのビューにもflashメッセージが残ってしまいました。

次にnewアクションが動くことによって表示が消えるのが確認できます。
これでは困るのでflash.nowを使用します。

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を使った時の挙動を確認してみます。

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.keep

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を使った時と同じ挙動になります。

flash.now

ぴっかちゃん

もっとRuby on Railsを体系的に学びたい!という方は、複数人での開発体制やテストコードの書き方など実際の開発現場での役に立つこちらの参考書が良いでしょう。

flashをbootstrapで表示しよう

cssのフレームワークであるbootstrapを使うとflashメッセージをかっこよく表示させることができます。

railsにbootstrapを導入しよう

railsにbootstrapを導入するにはGemfileにgemを追加します。
下記のコードをGemfileに追記し、bundle installコマンドを実行しましょう。

Gemfile -->
1
2
gem 'jquery-rails'
gem 'bootstrap', '~> 4.1.1'

次にapp/assets/stylesheets/application.cssの拡張子をscssに変更し、下記の一文を追記します。

application.scss -->
1
@import "bootstrap";

bootstrapのjavascriptを対応させるために下記のコードをapp/assets/javascripts/application.jsに追記します。

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

上のコードのprimaryの部分が色を指定する箇所になります。
この部分をbootstrapで定義されているクラス名に変更することにより色を変えることができます。

上のprimary以外にも下記の色が定義されています。

secondary

1
<p class="alert alert-secondary">

secondary

success

1
<p class="alert alert-success">

success

danger

1
<p class="alert alert-danger">

danger

warning

1
<p class="alert alert-warning">

warning

info

1
<p class="alert alert-info">

info

light

1
<p class="alert alert-light">

light

dark

1
<p class="alert alert-dark">

dark

部分テンプレートに合わせる必要があるので、キー名に色の指定を設定しましょう。

コントローラー -->
1
2
3
4
5
6
# 例:緑色で表示させたい場合
if article.save
  flash[:success] = "登録が完了しました。"
  redirect_to root_path
else
  ~  ~

こうすれば下記のkeyの部分に色を指定するsuccessが入るので、緑色のデザインが適用されます。

layout/_flash.html.erb
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">&times;</button>
</div>

上のように記述するとbootstrapのjavascriptが実行され、×ボタンを押すとflashメッセージが削除されます。
今回「×」は特殊文字の&amp;times;で指定しています。

特殊文字とは?

文字コードで英字、数字、カナ、かな、漢字以外のものを指します。
今回の「×」や「←」などは特殊文字です。

button

このように自分でflashメッセージを削除することができるようになりました!

ただし、これはbootstrapを導入していないと使えないので、導入していない場合は自分でjavascriptを作成する必要があるので注意しましょう。

このようにflashメッセージはとても便利な機能です。
ただflashメッセージはrails側で保存されるのではなく、自分のPCのCookieにデータを保存して表示させています。

Cookieが無効になっているブラウザでは表示されないので気をつけましょう。

この記事のまとめ

  • flashは簡単なメッセージを1回だけ表示させる事ができる便利な機能のこと
  • flashメッセージ用の部分テンプレートを作成しておくと便利!
  • 同じリクエスト内でflashを使う時はflash.nowを使う