Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 无法理解登录后使用Rails重定向的设计_Ruby On Rails_Redirect_Devise - Fatal编程技术网

Ruby on rails 无法理解登录后使用Rails重定向的设计

Ruby on rails 无法理解登录后使用Rails重定向的设计,ruby-on-rails,redirect,devise,Ruby On Rails,Redirect,Devise,我是一个rails/Desive新手,在这方面我已经做了几个月的搜索,还没有找到解决方案 我试图做的事情似乎很简单:在使用Rails和Desive gem v 3.2.3成功登录事件后,将用户重定向到上一页,但我的所有登录重定向都将指向根路径。这很烦人,因为如果我给某人发送一个指向特定页面的链接,他们必须在其中进行身份验证,它会再次将他们重定向到主页 我知道其他问题也会问这个,但我想我是在问一个更高层次的问题,关于Desive中的代码 所以我的总体问题是:我对问题和解决方案的理解正确吗?为了解决

我是一个rails/Desive新手,在这方面我已经做了几个月的搜索,还没有找到解决方案

我试图做的事情似乎很简单:在使用Rails和Desive gem v 3.2.3成功登录事件后,将用户重定向到上一页,但我的所有登录重定向都将指向根路径。这很烦人,因为如果我给某人发送一个指向特定页面的链接,他们必须在其中进行身份验证,它会再次将他们重定向到主页

我知道其他问题也会问这个,但我想我是在问一个更高层次的问题,关于Desive中的代码

所以我的总体问题是:我对问题和解决方案的理解正确吗?为了解决这个问题,我需要:

存储用户会话中的上一页 重定向到after_sign_in_path函数中的该位置 我正在查看第177行designe lib/designe/controllers/helpers.rb中的一些代码注释:

# The default url to be used after signing in. This is used by all Devise
  # controllers and you can overwrite it in your ApplicationController to
  # provide a custom hook for a custom resource.
  #
  # By default, it first tries to find a valid resource_return_to key in the
  # session, then it fallbacks to resource_root_path, otherwise it uses the
  # root path. For a user scope, you can define the default url in
  # the following way:
然后在该文件的第204行:

def after_sign_in_path_for(resource_or_scope)
  stored_location_for(resource_or_scope) || signed_in_root_path(resource_or_scope)
end
这将引导我找到store_location.rb中方法的stored_location_:

因此,当新用户登录时,会调用SessionCreate中的代码:

# POST /resource/sign_in
def create
  self.resource = warden.authenticate!(auth_options)
  set_flash_message(:notice, :signed_in) if is_flashing_format?
  sign_in(resource_name, resource)
  yield resource if block_given?
  respond_with resource, location: after_sign_in_path_for(resource)
end
这将在我粘贴在上面的资源的路径中签名后调用。我的问题是:这就是我所需要的一切,能够将某人重定向到上一页而不是根路径吗?有什么我需要补充的吗?在资源的路径中的符号不为零之后,如何测试?还有谁有这方面的经验吗

以下是我的路由文件,仅供参考:

如果我的代码有用的话,我会很乐意透露更多的代码

提前谢谢大家,

布兰登 编辑 做了更多的挖掘来缩小范围。我注释掉了store_location.rb中的许多代码,以查看会话密钥是什么。注释掉if/else语句,因为它是一种导航格式,显然这意味着什么

  def stored_location_for(resource_or_scope)
    session_key = stored_location_key_for(resource_or_scope)
    puts "session_key = #{session_key}"
    puts "session = #{session}"
    puts "session[session_key] = #{session[session_key]}"
    # if is_navigational_format?
    #   puts "is navigational"
    #   session.delete(session_key)
    # else
    #   puts "is not navigational"
    puts "session[session_key] = #{session[session_key]}"
    session[session_key]
    # end
  end
我在这个方法中添加了一些put语句,它绑定到session_key

  def stored_location_key_for(resource_or_scope)
    scope = Devise::Mapping.find_scope!(resource_or_scope)
    "#{scope}_return_to"
  end
以下是命令行中的输出:

Started POST "/users/sign_in" for 127.0.0.1 at 2015-05-03 22:34:31 -0500
Processing by Devise::SessionsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"/Xjy/neoPX2nGqpz+FtACjtTx4nnkhiRuVln44Zi4qI=", "user"=>{"email"=>"brandon.a.hay@gmail.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"}
  User Load (0.3ms)  SELECT  "users".* FROM "users"  WHERE "users"."email" = 'brandon.a.hay@gmail.com'  ORDER BY "users"."id" ASC LIMIT 1
   (0.1ms)  begin transaction
  SQL (0.3ms)  UPDATE "users" SET "current_sign_in_at" = ?, "last_sign_in_at" = ?, "sign_in_count" = ?, "updated_at" = ? WHERE "users"."id" = 7  [["current_sign_in_at", "2015-05-04 03:34:31.179646"], ["last_sign_in_at", "2015-05-04 03:32:08.608830"], ["sign_in_count", 65], ["updated_at", "2015-05-04 03:34:31.181312"]]
  Spree::Role Load (0.1ms)  SELECT  "spree_roles".* FROM "spree_roles"  WHERE "spree_roles"."name" = 'admin' LIMIT 1
  SQL (0.1ms)  INSERT INTO "spree_roles_users" ("role_id", "user_id") VALUES (?, ?)  [["role_id", 1], ["user_id", 7]]
   (1.5ms)  commit transaction
session_key = user_return_to
session = #<ActionDispatch::Request::Session:0x007fc7c4af34b0>
session[session_key] =
stored location =
session_key = user_return_to
session = #<ActionDispatch::Request::Session:0x007fc7c4af34b0>
session[session_key] =
Redirected to http://localhost:3000/

因此,存储的位置键返回用户类并将其绑定到作用域。session_key返回用户_return_to,session返回动作分派请求session,session[session_key]为nil。有人能帮我弄明白吗?

您需要在控制器中重定向路由,如下所示

class HomeController < ApplicationController
    def index
        if user_signed_in?
            redirect_to blogs_index_path
        end
    end
end

转到terminal并键入rake routes,找到您想要的路径并将其重定向到那里。希望这有帮助

看起来尝试的位置从未存储或存储在错误的位置。看看这个代码

当身份验证失败时,始终调用Failure app。您可以在第57行看到它存储了访问的uri。您可以尝试在此处进行调试

我能想出几个原因来解释为什么这不起作用:

您正在使用不存储位置的不同故障应用程序 失败应用程序中的会话密钥不正确 有一些代码可以清除存储位置
如果您找不到导致此问题的原因,您可以尝试将代码从Desive failure应用程序复制到您的应用程序控制器。使用prepend_before_filter在任何其他before_filter之前存储位置。

这篇文章的答案解决了我的问题:

我必须在我的应用程序控制器中添加商店位置回拨:

#application_controller.rb
before_filter :store_current_location, :unless => :devise_controller?

def store_current_location
  store_location_for(:user, request.url)
end

也许spree是在路径方法中签名后定义它自己的。调试它的简单方法是在Desive代码中添加一些puts语句,重新加载rails服务器并检查此方法返回的值。我没有时间仔细阅读,但我猜这可能会有所帮助,感谢您注意到Spree Michal。我应该提到这一点。我查看了他们的代码,似乎对登录重定向过程没有任何影响。@Michal,我找到了更多关于Desive和方法的存储位置的信息。你能回答我上面问题中的编辑吗?我会在2分钟后发布…你的疯狂版是什么?谢谢,我来试一试。从前面的一条评论中也可以看到这一点。这里的链接对我很有用:
class HomeController < ApplicationController
    def index
        if user_signed_in?
            redirect_to blogs_index_path
        end
    end
end
#application_controller.rb
before_filter :store_current_location, :unless => :devise_controller?

def store_current_location
  store_location_for(:user, request.url)
end