Railsのコントローラでredirect_to処理を記述し、:notice, :alert, :flashを記述した後に、転送先のビューを開くと、<%= notice %>
や、<%= flash[:キー名] %>
、<%= alert %>
の部分になにも表示されず、
データがパラメータとして、 ?notice=値&flash=値 として渡されることがあります。
この原因と対処法について解説しています。
発生する状況と原因
発生する状況
この症状が発生するのは、ルートパスをコントローラ名とアクション名、または、アクション名のみで指定したときです。
#コントローラとアクションを指定
redirect_to controller: :コントローラ名, action: :アクション名
#同じコントローラ内でアクションを指定
redirect_to action: :アクション名
この指定の後に、カンマでnoticeやalert, flashをつけると発生します。
↓ パラメータとして表示される例
#コントローラとアクションを指定
redirect_to controller: :コントローラ名, action: :アクション名, notice: "転送しました。"
#同じコントローラ内でアクションを指定
redirect_to action: :アクション名, notice: "転送しました。"
実例
class UsersController < ApplicationController
def index
redirect_to action: :show, notice: "転送しました。"
end
def show
end
end
↓転送結果のURL
http://localhost:3001/users/show?notice=転送しました。
原因
この症状が発生する理由は、redirect_toの中で、controller: や action: の後に、オプションをつけると、redirect_toのオプションではなく、controllerやactionに渡す引数とみなされるためです。
つまり、以下は同じ処理になります。
#コントローラとアクションを指定
redirect_to controller: :コントローラ名, action: :アクション名, notice: "転送しました。"
redirect_to ({controller: :コントローラ名, action: :アクション名, notice: "転送しました。"})
#同じコントローラ内でアクションを指定
redirect_to action: :アクション名, notice: "転送しました。"
redirect_to ({action: :アクション名, notice: "転送しました。"})
対処法
:notice, :alert, :flash がパラメータとしてみなされないようにするためには、それぞれのオプションが、controller: やaction: ではなく reidrect_toのオプションであることがわかるように、({ })で区切りをつけます。
noticeやalertの場合
#コントローラとアクションを指定
redirect_to ({controller: :コントローラ名, action: :アクション名}), notice: "転送しました。"
#同じコントローラ内でアクションを指定
redirect_to ({action: :アクション名}), notice: "転送しました。"
あとは、転送先のビューファイルに、<%= notice %>
や <%= alert %>
を記述すれば受け取ることができます。
flashの場合
flashの場合はキー名も指定する必要があります。
#コントローラとアクションを指定
redirect_to ({controller: :コントローラ名, action: :アクション名}), flash: { key名: "転送しました。"}
#同じコントローラ内でアクションを指定
redirect_to ({action: :アクション名}), flash: { key名: "転送しました。"}
あとは、転送先のビューファイルに、<%= flash[:キー名] %>
を記述すれば受け取ることができます。
実例
例1:notice, alert, flashの表示
実際に、notice, alert, flashを表示させてみます。
コントローラ
usersコントローラのindexアクションにアクセスすると、同じコントローラのshowアクションに飛ばします。
class UsersController < ApplicationController
def index
redirect_to ({action: :show}), notice: "noticeです。", flash: { info:"flashです。"}, alert: "alertです。"
end
def show
end
end
ビューファイル
転送先のビューファイルの中で、notice, flash, alertの内容を表示します。
<h1>Users#show</h1>
<p> <%= notice %> </p>
<p> <%= flash[:info] %> </p>
<p> <%= alert %> </p>
▼ブラウザの表示
http://localhost:3001/users/indexにアクセスすると、次のページが開けます。
notice, flash, alertが表示されていることがわかります。
例2:パラメータも一緒に渡す
notice, alert, flashと合わせてパラメータも渡します。
コントローラ
usersコントローラのindexアクションにアクセスすると、同じコントローラのshowアクションに飛ばします。
カッコ({ })
の中に パラメータを記述します。ここでは、idとnameの2つを指定します。
class UsersController < ApplicationController
def index
redirect_to ({controller: :users, action: :show, id: "1234", name: "test"}), notice: "noticeです。", flash: { info:"flashです。"}, alert: "alertです。"
end
def show
end
end
ビューファイル
転送先のビューファイルの中で、notice, flash, alertおよび、パラメータを表示します。
<h1>Users#show</h1>
<p> <%= notice %> </p>
<p> <%= flash[:info] %> </p>
<p> <%= alert %> </p>
<p>ID: <%= params[:id] %> 名前: <%= params[:name] %> </p>
▼ブラウザの表示
http://localhost:3001/users/indexにアクセスすると、次のページが開けます。
URLがhttp://localhost:3001/users/show?id=1234&name=testとなり、指定したパラメータが渡っていることがわかります。