Ruby on Railsのフラッシュメッセージは、リダイレクト先のページに一時的なデータ(通知メッセージなど)を渡すための仕組みです。通常のインスタンス変数はリダイレクト時にリセットされるため、成功メッセージやエラーメッセージをリダイレクト先に表示するにはフラッシュを使う必要があります。この記事では、フラッシュメッセージの使い方と活用パターンを解説します。
基本的な使い方
flashハッシュにキーと値を設定し、redirect_toでリダイレクトすると、リダイレクト先のページでそのデータを参照できます。
class PostsController < ApplicationController
def create
@post = Post.new(post_params)
if @post.save
flash[:notice] = "投稿を作成しました"
redirect_to @post
else
render :new
end
end
def destroy
@post = Post.find(params[:id])
@post.destroy
flash[:alert] = "投稿を削除しました"
redirect_to posts_path
end
endフラッシュに設定したデータは次のリクエストで1回だけ参照でき、その後は自動的に消去されます。この特性により、ページをリロードするとメッセージは消えます。
redirect_toとの省略記法
redirect_toのnoticeやalertオプションを使うと、フラッシュの設定とリダイレクトを1行で書けます。
class PostsController < ApplicationController
def create
@post = Post.new(post_params)
if @post.save
redirect_to @post, notice: "投稿を作成しました"
else
render :new
end
end
def destroy
@post = Post.find(params[:id])
@post.destroy
redirect_to posts_path, alert: "投稿を削除しました"
end
endこの省略記法はflash[:notice] = "..."とredirect_toを組み合わせたものと同じ動作です。コードがすっきりするため、こちらの書き方が推奨されます。
ビューでのフラッシュ表示
フラッシュメッセージをビューに表示するには、レイアウトファイルに以下のようなコードを追加します。
<body>
<% flash.each do |type, message| %>
<div class="alert alert-<%= type %>">
<%= message %>
</div>
<% end %>
<%= yield %>
</body>flash.eachでフラッシュに格納されたすべてのメッセージを表示しています。typeにはnoticeやalertなどのキーが入るため、CSSクラスに利用してスタイルを変えることができます。
flash.nowの使い方
flash.nowは、リダイレクトせずに現在のリクエスト内でフラッシュメッセージを表示する場合に使います。
class PostsController < ApplicationController
def create
@post = Post.new(post_params)
if @post.save
redirect_to @post, notice: "投稿を作成しました"
else
flash.now[:alert] = "入力内容にエラーがあります"
render :new
# renderなのでflash.nowを使う
end
end
endrenderはリダイレクトと異なり新しいリクエストを発生させないため、通常のflashを使うと次のリクエストまでメッセージが残ってしまいます。flash.nowを使えば現在のリクエストでのみメッセージが表示されます。
redirect_toのときはflashを、renderのときはflash.nowを使うと覚えましょう。間違えるとメッセージが表示されなかったり、余計なタイミングで表示されたりします。
カスタムフラッシュキー
noticeとalert以外にも、任意のキーでフラッシュを使えます。
flash[:success] = "正常に完了しました"
flash[:warning] = "注意が必要です"
flash[:info] = "お知らせがあります"ただし、redirect_toの省略記法(notice:、alert:)が使えるのはnoticeとalertのみです。カスタムキーを使う場合は明示的にflash[:key] = valueと書く必要があります。
フラッシュには文字列など簡潔なデータのみを保存しましょう。大きなオブジェクトや機密情報はフラッシュではなくセッションやデータベースに保存してください。フラッシュデータはクッキーを介してやり取りされるため、サイズと安全性に制約があります。
まとめ
flash[:key] = "メッセージ"でリダイレクト先にデータを渡せるredirect_to path, notice: "..."の省略記法が便利- フラッシュデータは次のリクエストで1回だけ参照され、自動的に消去される
redirect_toにはflash、renderにはflash.nowを使う- レイアウトで
flash.eachを使ってすべてのメッセージを表示する - フラッシュには簡潔なデータのみを保存し、大きなデータは別の手段で管理する