如何在 Ruby On Rails 中重定向到上一页?

问题描述 投票:0回答:10

我有一个页面列出了所有具有可排序标题和分页的项目。

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 

我怎样才能让它发挥作用?

ruby-on-rails http-redirect
10个回答
342
投票

在编辑操作中,将请求 URL 存储在会话哈希中,该哈希可在多个请求中使用:

session[:return_to] ||= request.referer

成功保存后,在更新操作中重定向到它:

redirect_to session.delete(:return_to)

106
投票

为什么

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)

请注意,Rails 5 中已弃用

redirect_to(:back)
。您可以使用

redirect_back(fallback_location: 'something')
(参见 http://blog.bigbinary.com/2016/02/29/rails-5-improves-redirect_to_back-with-redirect-back.html


46
投票

我喜欢 Jaime 的方法,但有一个例外,每次都重新存储引用者对我来说效果更好:

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

原因是,如果您编辑多个对象,您将始终被重定向回使用 Jaime 的方法存储在会话中的第一个 URL。 例如,假设我有对象 Apple 和 Orange。我编辑 Apple 并将

session[:return_to]
设置为该操作的引用者。当我使用相同的代码编辑 Oranges 时,
session[:return_to]
将不会被设置,因为它已经被定义了。 因此,当我更新 Orange 时,我将被发送到之前 Apple#edit 操作的引用者。


35
投票

这就是我们在应用程序中的做法

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

这样,您只将最后一个 GET 请求存储在

:return_to
会话参数中,因此所有表单,即使多次 POSTed 也可以与
:return_to
一起使用。


26
投票

在 Rails 5 中,按照 Rails Guides 中的说明,您可以使用:

redirect_back(fallback_location: root_path)

“后退”位置是从 HTTP_REFERER 标头中提取的,不保证由浏览器设置。这就是为什么您应该提供“fallback_location”。


18
投票

request.referer
由Rack设置,设置如下:

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

只需执行

redirect_to request.referer
,它就会始终重定向到真正的引用页面或 root_path ('/')。 当将直接导航失败的测试传递到控制器抛出redirect_to :back

的特定页面时,这一点至关重要

2
投票
link_to 'get me back', :back

符号

:back
是您的瑞士军刀。


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

0
投票

我想知道这是否有效

  def edit
    if request.referer != request.original_url
        @return_here =  request.referer
    end

  end

并使用@return_here作为提交表单中的隐藏值。

当然,重新加载会终止此问题,因此只需根据需要返回默认回退即可。


0
投票

@Jaime Bellmyer 最受接受的答案是最好的,但有一个例外:

如果您有:

  • a
    show
    操作是 Rails Scaffold 的默认操作,并且是从
    edit
    show
    和返回
  • 的链接
  • 在索引视图中过滤您始终想要返回的参数

您需要更多代码,在我的示例中

application_controller
: :

  def set_return_to_path(exclude_string = nil)
    unless request.referer.include? exclude_string
      session[:return_to] = request.referer
    end
  end

动作内部:

def show
   set_return_to_path(edit_article_path(@article))
end

因此,在

show
操作中,当来自
edit
操作并反向时,您会跳过此操作。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.