flashを利用して、アクション実行後に簡単なメッセージを表示させることができます。
ログイン周りの処理において特に重宝されます。
(Sessionはモデルを持たない→ActiveRecordがエラーメッセージを吐かないから)
使い方
flash[:<キー>] = <メッセージ>で登録し、flash.each do |message_type, message|...で出力します。
flashとflash.now
flashの仲間にflash.nowがあり、
flash→次のアクションまでデータを保持する→redirect_toと一緒に使う
flash.now→次のアクションに移行した時点でデータが消える→renderと一緒に使う
という使い分けが必要です。
TODOアプリにflashを実装する
簡単なTODOアプリにflashを実装していきます。
・Ruby on Railsで簡単なアプリを作成
・RailsアプリをHerokuにデプロイする手順
・【Rails】バリデーションを実装する
・【Rails】ログイン機能を実装する
application.html.erbにflash表示領域を確保する
<!DOCTYPE html>
.
.
  <body>
    <% flash.each do |message_type, message| %>
      <%= message %>
    <% end %>
.
.
tasksコントローラーを修正する
redirect_toの前にflashを、renderの前にflash.nowをそれぞれ追加します。
class TasksController < ApplicationController
  before_action :logged_in_user, only:[:create, :edit, :update, :destroy]
  def index
    @tasks = Task.all
  end
  def new
    @task = Task.new
  end
  def create
    @task = Task.new(task_params)
    if @task.save
      flash[:success] = "タスクを追加しました。"
      redirect_to tasks_url
    else
      flash.now[:danger] = "登録に失敗しました。"
      render 'tasks/new'
    end
  end
  def edit
    @task = Task.find(params[:id])
  end
  def update
    @task = Task.find(params[:id])
    if @task.update(task_params)
      flash[:success] = "タスクを修正しました。"
      redirect_to tasks_url
    else
      flash.now[:danger] = "更新に失敗しました。"
      render 'tasks/edit'
    end
  end
  def destroy
    @task = Task.find(params[:id])
    @task.destroy
    flash[:success] = "タスクを削除しました。"
    redirect_to tasks_url
  end
  private
    def task_params
      params.require(:task).permit(:title)
    end
end
sessionsコントローラーを修正する
tasksコントローラー同様、redirect_toの前にflashを、renderの前にflash.nowを追加します。
class SessionsController < ApplicationController
  def new
  end
  
  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      flash[:success] = "ログインしました。"
      redirect_to root_url
    else
      flash.now[:danger] = "ログインに失敗しました。"
      render 'new'
    end
  end
  def destroy
    log_out if logged_in?
    flash[:success] = "ログアウトしました。"
    redirect_to root_url
  end
end