Devise和stored_location_for:你如何存储返回位置?

fea*_*ool 27 redirect devise ruby-on-rails-3

我有一个页面的路径是(例如)/ premises/92我正在显示"请[登录]或[注册]以获取更多信息"如果用户没有登录,我想要设计返回相同的用户登录后的/ premises/92页面.

我已经阅读了其他帖子,我想我理解设计stored_location_for应该如何工作.理论上,我可以把这样的东西放在我的ApplicationController:

def stored_location_for(resource)
  if (r = session[:return_to])
    session[:return_to] = nil
    r
  else
    super
  end
end
Run Code Online (Sandbox Code Playgroud)

我的问题是:我如何/在哪里设置会话[:return_to]?

我只想在用户点击[登录]或[注册]时设置会话[:return_to],但最好的方法是什么?

  • 用JavaScript装饰链接?这可行,但似乎很苛刻.
  • 在渲染页面之前将它设置在Premises Controller中?这似乎不正确:如果用户没有点击[登录]或[注册]链接怎么办?然后我将session [:return_to]设置为某个奇数值,如果用户从其他页面登录,可能会让我失望.
  • ?return_to=/premises/92查询字符串添加到[登录]和[注册]链接,并在RegistrationsController和SessionsController中检测并使用该信息设置会话[:return_to]?这似乎会起作用,但也很苛刻.

这些都闻不对劲.为stored_location_for设置状态的普遍接受的技术是什么?

ror*_*rra 25

设计使用

session["#{scope}_return_to"]
Run Code Online (Sandbox Code Playgroud)

因此,session["user_return_to"]如果您的身份验证模型是User,则可以使用.

  • 我很难理解这个答案是如何运作的 - 它说的是要改变什么,而不是在哪里.正如OP所说,他应该为他的所有链接添加一个?param,并在控制器上处理它,还是以某种方式通过rails神奇地处理? (7认同)
  • @kikito:这是你的控制器.你可以在任何你知道你想回去的地方修改你的会话.因此,如果您正在渲染场所,包括登录链接,那么您可以在PremisesController#show action中设置session [:user_return_to] = premise_path(@premise). (4认同)

Jer*_*nch 8

我发现整个设计重定向的东西很混乱.

在@rorra说Devise使用的地方session["#{scope}_return_to"],他意味着Devise默认after_sign_in_path_for(resource)将通过该方法使用该变量stored_location_for(resource).

因此,您应该将要存储的位置保存在变量中session["#{scope}_return_to"],这通常是session["user_return_to"].为此,请将以下内容放在application_controller.rb中:

after_action :store_location

def store_location
  # store last url - this is needed for post-login redirect to whatever the user last visited.
  if (request.fullpath != "/users/sign_in" &&
      request.fullpath != "/users/sign_up" &&
      request.fullpath != "/users/password" &&
      request.fullpath != "/users/sign_out" &&
      !request.xhr?) # don't store ajax calls
    session["user_return_to"] = request.fullpath 
  end
end
Run Code Online (Sandbox Code Playgroud)

在某些情况下,您不需要定义after_sign_in_path_for(resource)方法,因为设计的默认方法将为您执行所有重定向,如果它们没有可用的重定向URL,您将被重定向到资源根路径(通常是用户根路径),如果没有如果存在,您将被重定向到根路径.但是,如果没有可用的重定向网址,您希望自定义用户的发送位置,请将以下内容添加到application_contorller.rb(并相应更改root_path):

def after_sign_in_path_for(resource)
  stored_location_for(resource) || root_path
end
Run Code Online (Sandbox Code Playgroud)


use*_*245 6

Devise"#{resource}_return_to"在会话中查找密钥.

我在这里引用API:

默认情况下,它首先尝试#{resource}_return_to在会话中查找有效密钥,然后回退到#{resource}_root_path,否则使用root_path.

这是API的链接

  • 铁轨还是设计? (3认同)