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

时间:2010-01-26 14:30:46

标签: ruby-on-rails redirect

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

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的新手。

9 个答案:

答案 0 :(得分:315)

在您的编辑操作中,将请求网址存储在会话哈希中,该哈希值可用于多个请求:

session[:return_to] ||= request.referer

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

redirect_to session.delete(:return_to)

答案 1 :(得分:95)

为什么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

答案 2 :(得分:45)

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

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

原因是如果您编辑多个对象,您将始终被重定向回使用Jaime方法存储在会话中的第一个URL。例如,假设我有Apple和Orange的对象。我编辑Apple并将session[:return_to]设置为该操作的引用者。当我使用相同的代码编辑橘子时,session[:return_to]将不会被设置,因为它已经被定义。因此,当我更新Orange时,我将被发送给之前Apple#edit动作的引用者。

答案 3 :(得分: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

答案 4 :(得分:18)

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

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

只需执行redirect_to request.referer,它将始终重定向到真正的引用页面或root_path('/')。当将直接导航失败的测试传递给控制器​​抛出redirect_to的特定页面时,这是必不可少的:返回

答案 5 :(得分:13)

在rails 5中,根据Rails指南中的说明,您可以使用:

redirect_back(fallback_location: root_path)

'''从HTTP_REFERER标头中提取位置,该标头不保证由浏览器设置。这就是为什么你应该提供一个' fallback_location'。

答案 6 :(得分: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

答案 7 :(得分:0)

不知道这样行不行

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

  end

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

当然,重新加载会杀死它,因此只需根据需要返回默认回退。

答案 8 :(得分:0)

link_to 'get me back', :back

符号 :back 是您的瑞士军刀。