flash のスコープは、次のリクエストまで有効である。
以下のように flash にメッセージを入れて画面を表示した場合
1 2 3 |
flash.message = "Error message" |
すぐに render するとその次のリクエストでも値が有効になり、エラーメッセージが再度表示されてしまう。
1 2 3 4 |
flash.message = "Error message" render(view:'/error') |
想定としては、redirect した時にリダイレクト先で表示した view に値を渡す場合である。
以下の場合だと、show にリダイレクトしてその先で表示した view のリクエストまで有効であるので、その先には表示されない。
1 2 3 4 |
flash.message = "Error message" redirect(action: "show", id: dataId) |
flash を使って、redirect ではなく render で表示した場合にメッセージの再表示を抑える方法は二つある。
- flash のメッセージを表示したら flash の内容を初期化する
- render の時は、flash ではなく request を使う
view 側で、以下のように flash.message に null を入れる
1 2 3 4 5 6 |
<g:if test="${flash.message}"> <div>${flash.message}</div> <% flash.message = null %> </g:if> |
contorller 側では以下のようにする
1 2 3 4 |
request.message = "Error message" render(view:'/error') |
view 側では以下のようにする
1 2 3 4 5 |
<g:if test="${request.message}"> <div>${request.message}</div> </g:if> |
お勧めというか、私がやった対応は、上記 1 の対応。
処理によって、request だったり flash だったり切り分けるのが面倒なので、画面に表示する情報は全て flash スコープ変数に入れた。