どうした?
Sessionsコントローラでログイン機能を実装したところ、flash.nowが表示されなかった。
minitestのログインテストでは
assert !flash.empty?
はtrueを返していた。
開発環境
$ ruby -v
=> ruby 3.1.2p20
$ rails -v
=> Rails 6.1.7
解決方法
before
sessions_controller.rb
def create
@user = User.find_by(email: params[:session][:email])
if @user && @user.authenticate(params[:session][:password])
log_in(@user)
remember(@user)
flash.now[:info] = "ログインしました"
redirect_to root_path
else
flash.now[:notice] = "パスワードが間違っているか、存在しないユーザーです"
@email = params[:email]
render "new"
end
end
↓↓↓↓↓↓↓↓↓↓↓
after
sessions_controller.rb
def create
@user = User.find_by(email: params[:session][:email])
if @user && @user.authenticate(params[:session][:password])
log_in(@user)
remember(@user)
flash[:info] = "ログインしました" #.nowを削除
redirect_to root_path
else
flash.now[:notice] = "パスワードが間違っているか、存在しないユーザーです" #.nowは消さない
@email = params[:email]
render "new"
end
end
これでフラッシュメッセージが表示されます。
解説
こちらの記事がとっても分かりやすかったです。
今回の例でいうと、ログイン成功時(if文の中身)はredirect_toでhomeコントローラをまたいでroot_pathにページ遷移するため、この時点で既にflashの寿命は終えているのです。
対してelse文ではrenderを使用しており、ページ遷移先でflashの寿命を終えさせたいので、flash.nowを使用する必要があるのです。
まとめ
flash.nowを知ったとき、その便利さに「常にこれでいいじゃん」と思ってしまいました。
しかし、物事には適切な使用方法というものがあるもので、、
flash.nowを使うべきシーンを紹介する記事はたくさんありますが、今回はその便利さに盲目になってしまった男がflash.nowを使ってはいけないシーンを紹介しました。