Ruby On Rails에서 이전 페이지로 리디렉션하는 방법은 무엇입니까?


186

정렬 가능한 헤더와 페이지 매김이있는 모든 프로젝트를 나열하는 페이지가 있습니다.

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

프로젝트 중 하나를 편집하기로 선택했습니다

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

19
여러 개의 탭을 열지 않아도이 논리를 혼동합니까?
jones

12
당신은 단지 수 없습니다 redirect_to request.referer?
Elle Mundy

1
@DanMundy 아니요, request.referer.referer가능하다면 가능해야합니다. @Jaime Bellmyer 왜 ||=?
x-yuri

@ 존스 예. 다른 모델 편집으로 전환하면 혼란이 있습니다. 나는 또한 || =
Mauro

99

redirect_to(:back)당신을 위해 작동 하지 않습니다, 왜 안돼?

redirect_to(:back)나를 위해 매력처럼 작동합니다. 그것은 단지 지름길입니다. redirect_to(request.env['HTTP_REFERER'])

http://apidock.com/rails/ActionController/Base/redirect_to(pre Rails 3) 또는 http://apidock.com/rails/ActionController/Redirecting/redirect_to(Rails 3)

참고 redirect_to(:back)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됩니다. 그러나 다른 목적으로는 잘 작동합니다.
Kris

즉, OP는 두 번 다시 리디렉션하려고합니다. 나는 단지 그가 할 수있는 내기 redirect_to projects_path.
x-yuri

네. redirect_back은 Rails 5에서도 잘 작동하지 않습니다
strizzwald

@strizzwald "잘 작동하지 않는다"는 무슨 뜻입니까? 세부 사항이 있습니까?
Pascal

@pascalbetz, 내가 의미하는 바가 HTTP_REFERER설정되어 있지 않으면 이 경우 예외를 피해야한다는 것입니다 ActionController::RedirectBackError. 내 이해에서, redirect_back당신은 강제로 제공하기 때문에 예외 처리를 요구하지 않습니다 fallback_location. 아마도 '잘 작동하지 않습니다'는 올바른 방법이 아닐 수도 있습니다.
strizzwald

45

한 가지 예외를 제외하고 Jaime의 방법이 마음에 들었습니다. 매번 참조자를 다시 저장하는 것이 좋습니다.

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

여러 객체를 편집하는 경우 항상 Jaime의 방법으로 세션에 저장 한 첫 번째 URL로 다시 리디렉션되기 때문입니다. 예를 들어, Apple과 Orange 객체가 있다고 가정 해 봅시다. Apple을 편집하고 session[:return_to]해당 조치의 참조 자로 설정됩니다. 동일한 코드를 사용하여 오렌지를 편집 session[:return_to]하려고하면 이미 정의되어 있으므로 설정되지 않습니다. Orange를 업데이트하면 이전 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세션 매개 변수 에 마지막 GET 요청 만 저장 하므로 POST 된 여러 시간이 있더라도 모든 양식을 사용할 수 있습니다 :return_to.


3
request.request_uri더 이상 사용할 수 없으므로 request.fullpath대신 사용 하는 것이 좋습니다
anka

@anka가 업데이트되었습니다. 댓글 주셔서 감사합니다
MBO

2
that 꽤 좋다. 난 단지 일반적으로 사용하지 않는 제안 andorif문. 사용 &&하고 ||대신. 자세한 내용은 여기를 참조하십시오 .
Achilles

19

Rails Guides의 지침에 따라 Rails 5에서 다음을 사용할 수 있습니다.

redirect_back(fallback_location: root_path)

'뒤로'위치는 HTTP_REFERER 헤더에서 가져와 브라우저에서 설정하지 않을 수 있습니다. 따라서 'fallback_location'을 제공해야합니다.


이 기능은 레일 5에 나타납니다.
Chambeur

@pSkarl 사용자에게 플래시 메시지에 문제가 있음을 알리기 위해 명령문 으로 notice객체를 전달하려면 어떻게해야 redirect_back합니까?
alexventuraio

2
글쎄, 나는 이것을함으로써 이것을 해결할 수있다 : redirect_back(fallback_location: root_path, notice: "Something went wrong!"). 희망 이 있었다 어떻게 든 도움이됩니다.
alexventuraio

18

request.referer 랙으로 설정되며 다음과 같이 설정됩니다.

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

그냥 a를 수행 redirect_to request.referer하면 항상 실제 참조 페이지 또는 root_path ( '/')로 리디렉션됩니다. 이는 컨트롤러가 redirect_to : back을 던지는 특정 페이지로 직접 탐색하는 경우 실패한 테스트를 전달할 때 필수적입니다.


확실하지가에 있지만 랙 소스에서보고 된 파일이 어떻게되어 referer의 경우로 정의 하였다 2011년 3월 28일 , 그것은 그것의로 정의하는 방법이다 오늘 . 즉 || '/', 정의의 일부가 아닙니다.
maček 님이

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.