redirct_to :back で前のページへ戻ると、それに関連して。
redirct_to :back で前のページへ戻る
# in controller
redirect_to :back
# in view
link_to :back
で前のページに戻れる。
導線がたこ足みたいなページでとりあえず前のページに戻るボタンがあったら便利だな、とか。
(もしかしたらそれはそもそもの設計を考え直したり、パンくずリストとか別のことを考えた方がいいのかもしれない。
純粋に自分用のツールならブラウザバックを使う())
で、便利だと思って深く考えずに使っていたらコントローラのテストで詰んだ。
エラーと対処法
(ActionController::RedirectBackError) "No HTTP_REFERER was set in the request to this action ...
refererという単語に聞き覚えがあったのだけど、よく分からず
(こういうことがよくある……)
http://stackoverflow.com/questions/771656/correctly-doing-redirect-to-back-in-ruby-on-rails-when-referrer-is-not-availabl
などを見たら、要するに前のページへ戻る、の前のページの情報がない、とのこと。
テストではいきなりそのアクションのurlを叩くという真似をしたので起きたみたい。
対処法としては、とりあえず発生したエラーを拾ってやって、例外処理の中で別のアドレスへリダイレクトさせる。
begin
redirect_to :back
rescue ActionController::RedirectBackError
redirect_to root
end
テストは無事とおるようになったけど、なんだか不安になったのでもう少し調べた。
ActionControllerとは
ActionControllerってTestUnitではcontrollerのテストのクラスのスーパークラスにそういう文字列があった気がする。
require 'test_helper'
class SampleControllerTest < ActionController::TestCase
だから、上のエラーを見たとき、もしやこれ、テストの環境でだけ発生するのか、
Railsの環境で発生するのか(そうだったら、そもそもテストに使えてないしそんなわけないだろうが)、
実際の環境に存在しないエラーの処理を本番環境のコードに埋め込むとかやだーとか。
要らない心配をした。
によると(もっといろいろあったけど)、
- ActionController::Base
- ActionController::TestCase
の2つのクラスがあって、ActionController::TestCaseはActionController::Baseのテスト用のクラス。
同じようにレスポンスを返し、同じようにエラーを吐く(と思われる)。
ApplicationControllerはActionControllerを継承しているので、
ActionController::RedirectBackErrorに対応するって書いていても大丈夫。
関係ないけど、testunit系でテンプレートのテストってこんな感じなのか。
ActionController::TemplateAssertions
redirect_to :back で呼び出されるrefererはどの変数に入っているのか
例外処理書かなくても入ってなければセットすればいいじゃない、とも思った。
redirect_to のオプションについて
:back - Back to the page that issued the request. Useful for forms that are triggered from multiple places. Short-hand for redirect_to(request.env["HTTP_REFERER"])
とあるので、request.env["HTTP_REFERER"]に入っているらしい。
アドレスして来たユーザのIPアドレスの取得などもrequest.envの要素路して含まれているみたい。
さて、これをstubさせて、とか思ったけど、前段の理由で、実環境でいきなりアドレスを叩いた場合にも起こりうるのだから止める。