Ruby On Railsで前のページにリダイレクトする方法は?


186

並べ替え可能なヘッダーとページネーションがあるすべてのプロジェクトを一覧表示するページがあります。

path:
/projects?order=asc&page=3&sort=code

プロジェクトの1つを編集することを選択します

path:
projects/436/edit

そのページで[保存]をクリックすると、プロジェクトのコントローラー/更新メソッドが呼び出されます。コードを更新した後、特定のプロジェクトをクリックして編集する前にいたパスにリダイレクトします。つまり、同じ並べ替えで同じページを表示したいのです。

link_to(:back)を見て、:backがredirect_to(:back)で機能するかもしれないと思っていましたが、それは大丈夫です。

puts YAML::dump(:back) 
yields the following:
:back 

これを機能させる方法に関するアイデア。簡単に解決できる問題のようですが、RoRは初めてです。

回答:


323

編集アクションで、リクエストURLをセッションハッシュに保存します。セッションハッシュは、複数のリクエストで利用できます。

session[:return_to] ||= request.referer

次に、保存が成功した後、更新アクションでそれにリダイレクトします。

redirect_to session.delete(:return_to)

68
redirect_to session.delete(:return_to)更新アクションでお勧めします。これは、不要になったため、セッションから値をクリーンアップします。
stigi 2012年

19
複数のタブを開いていると、このロジックが混乱しませんか?
ジョーンズ2013年

12
あなただけではないのですredirect_to request.refererか?
Elle Mundy 2014

1
@DanMundyいいえ、それが機能するためにはrequest.referer.referer、それが可能である場合、それはでなければなりません。@Jaime Bellmyerなんで||=
x-yuri 2015年

@jonesはい。別のモデル編集に切り替えると混乱もあります。|| =
マウロ

99

なぜうまくいかredirect_to(:back)ないのですか?

redirect_to(:back)私にとっては魅力のように機能します。それは単なるショートカットです redirect_to(request.env['HTTP_REFERER'])

http://apidock.com/rails/ActionController/Base/redirect_to(Rails 3以前)またはhttp://apidock.com/rails/ActionController/Redirecting/redirect_to(Rails 3)

redirect_to(:back)Rails 5では非推奨となっていることに注意してください。

redirect_back(fallback_location: 'something')代わりに(http://blog.bigbinary.com/2016/02/29/rails-5-improves-redirect_to_back-with-redirect-back.htmlを参照)


12
redirect_to :back私にとってもうまく機能しません。たとえば、にアクセスすると/posts/new、これは次のリクエストのリファラーとして設定されるため、フォームが正常に送信された後、フォームが再び表示されます/posts/new。ただし、他の目的には適しています。
クリス

つまり、OPは2回リダイレクトを元に戻したいと考えています。きっと彼はできるだろうredirect_to projects_path
x-yuri

うん。redirect_backはRails 5では同様に機能しません
strizzwald '18

@strizzwald「うまくいかない」とはどういう意味ですか?詳細は?
Pascal

@pascalbetz、私が意味したことは、HTTP_REFERERが設定されていない場合、を取得する可能性がActionController::RedirectBackErrorあるということです。その場合、この例外から救出する必要があります。私の理解では、をredirect_back提供する必要があるため、を使用しても例外処理は必要ありませんfallback_location。多分「うまくいかない」というのは、正しい言い方ではないかもしれません。
strizzwald

45

私はJaimeの方法が好きですが、例外が1つあります。リファラーを毎回再保存するほうがうまくいきました。

def edit
    session[:return_to] = request.referer
...

その理由は、複数のオブジェクトを編集した場合、常にJaimeのメソッドを使用してセッションに保存した最初のURLにリダイレクトされるためです。たとえば、AppleとOrangeのオブジェクトがあるとします。私はAppleを編集しsession[:return_to]、そのアクションのリファラーに設定されます。同じコードを使用してオレンジを編集しようとするsession[:return_to]と、すでに定義されているため設定されません。オレンジを更新すると、前のApple#editアクションのリファラーに送信されます。


はい、でも、誤って同じURLが現在の場所に保存されている場合の対処方法を教えていただけますか?あなたはリンゴにいて、リンゴから来ました。そして、あなたは以前の場所が欲しい
Uko

33

これが私たちのアプリケーションでのやり方です

def store_location
  session[:return_to] = request.fullpath if request.get? and controller_name != "user_sessions" and controller_name != "sessions"
end

def redirect_back_or_default(default)
  redirect_to(session[:return_to] || default)
end

この方法では、:return_toセッションparamに最後のGETリクエストのみを格納するため、すべてのフォームは、複数回POSTされた場合でも機能し:return_toます。


3
request.request_uriは利用できなくなったので、request.fullpath代わりに使用することをお勧めします
anka

@anka更新しました。コメントをありがとう
MBO

2
うん、それはかなり良い。私は、一般的に使用しないように示唆しているandorしてifステートメント。使用&&して||代わりに。詳細はこちら
アキレス

19

Rails 5では、Railsガイドの指示に従って、以下を使用できます。

redirect_back(fallback_location: root_path)

「戻る」場所は、ブラウザによる設定が保証されていないHTTP_REFERERヘッダーから取得されます。そのため、「fallback_location」を指定する必要があります。


この機能は、レール5に表示されます
Chambeur

@pSkarl フラッシュメッセージで問題が発生したことをユーザーに知らせるためにnoticeredirect_backステートメントを使用してオブジェクトをどのように渡すことができますか?
alexventuraio 16

2
まあ、私はこれを解決することができredirect_back(fallback_location: root_path, notice: "Something went wrong!")ます:それが何らかの形で役立つことを願っています。
alexventuraio 16

18

request.referer ラックによって設定され、次のように設定されます。

def referer
  @env['HTTP_REFERER'] || '/'
end

a redirect_to request.refererを実行するだけで、常に真の参照ページまたはroot_path( '/')にリダイレクトされます。これは、コントローラがredirect_to:backをスローする特定のページへの直接ナビゲーションの場合に失敗するテストに合格する場合に不可欠です。


必ずラックのソースではなく見ていたではない、どのファイル、これはどのようにあるrefererのと定義した2011年3月28日、それはそれはのように定義される方法である今日。つまり、|| '/'は定義の一部ではありません。
マセック

1

興味のある方のために、MBOの元の答え(rails 4.2.4、ruby 2.1.5に対して書かれたもの)を拡張した私の実装を以下に示します。

class ApplicationController < ActionController::Base
  after_filter :set_return_to_location

  REDIRECT_CONTROLLER_BLACKLIST = %w(
    sessions
    user_sessions
    ...
    etc.
  )

  ...

  def set_return_to_location
    return unless request.get?
    return unless request.format.html?
    return unless %w(show index edit).include?(params[:action])
    return if REDIRECT_CONTROLLER_BLACKLIST.include?(controller_name)
    session[:return_to] = request.fullpath
  end

  def redirect_back_or_default(default_path = root_path)
    redirect_to(
      session[:return_to].present? && session[:return_to] != request.fullpath ?
        session[:return_to] : default_path
    )
  end
end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.