仅在root_path上登录后才重定向用户

我的Rails应用程序上有一个root_path ,它不受用户保护,即它是一个简单的门户网站主页,带有登录表单。

用户登录后,我希望它转到dashboard_path

我做到了这个:

 def signed_in_root_path(scope_or_resource) dashboard_path end 

这显然应该在用户登录时使用,并且我不希望它转到root_path ,同时仍然保持用户返回到前一页,如果它尝试到达受限区域并且它要么超时还是没有超时登录。

即:

restricted_pa​​ge – > login – > restricted_pa​​ge_but_logged_in

我不想改变这种行为,这就是为什么我没有使用after_sign_in_path ,但是如果它在root_path ,或者想要在不需要用户身份validation的任何路由上重定向它。

我的问题是这不起作用。 登录后,我将被重定向回root_path ,我认为这是因为之前触发了after_sign_in_path

有没有办法做到这一点? 谢谢!

编辑:这是我第二次登录时工作,即我转到root_path ,登录,获取闪存消息,说明我已登录,并在root_path上的表单上再次输入用户名和密码。 我成功地被重定向到dashboard_path 。 不过,不是我想要的行为。

只是一个想法

您可以为登录的URL定义两个根URL,它将指向仪表板,第二个用于非签名用户,这将指向登录页面

根据routes.rb中的一些约束定义不同的根URL

登录用户的根URL

 constraints(AuthenticatedUser) do root :to => "dashboard" end 

非签名用户的根URL

 root :to=>"users/signin" 

然后在lib / authenticated_user.rb中创建类AuthenticatedUser

 class AuthenticatedUser def self.matches?(request) user_signed_in? end end 

现在如果用户登录root_url将指向仪表板,否则它将指向登录页面

你也可以创建两个根(尚未测试)

 root :to => "dashboard", :constraints => {user_signed_in?} root :to => "users/signin" 

更多关于约束http://edgeguides.rubyonrails.org/routing.html#request-based-constraints

注意

url的优先级基于创建顺序,首先创建 – >最高优先级资源

听起来你的问题太复杂了。 如果你进入覆盖路由变量,它只会导致头痛。 如果你使用的是单独的控制器,我建议使用beforefilter来要求登录并使用except param或在filter之前跳过它。 举个例子:

 class ApplicationController < ActionController::Base before_filter :require_login, :except => :root def root # Homepage end protected def require_login redirect_to login_path and return unless logged_in? end end 

(确保你已经定义了logged_in?)

如果您使用单独的控制器,它将看起来像这样:

 class HomepageController < ApplicationController skip_before_filter :require_login before_filter :route protected def route redirect_to dashboard_path and return if logged_in? end end 

关于登录后的正确路由,这将归结为您在创建会话时所执行的操作。 无论如何,此设置应该捕获任何登录尝试访问主页的人,并将它们路由到您的仪表板以及任何尝试访问受限内容的人(除root之外的任何内容)并将其路由到login_path

您可以覆盖after_sign_in_path_for方法,而不会丢失所需的行为。

  def after_sign_in_path_for(resource_or_scope) stored_location_for(resource_or_scope) || dashboard_path end 

如果current_user存在,我还会在root_path操作中添加一个重定向的条件。

 RootController.rb def index if current_user redirect_to dashboard_path else super #or whatever end end 

如果要将重定向添加到许多不受保护的操作,也可以使用before_filter。

我正在使用Omniauth,这种方法对我来说效果很好。 如果你正在使用不同的策略,我相信你可以修改它。

登录后,只需将它们重定向到root_path ,它就会将它们带到dashboard_path或您在下面的路径文件中设置的任何其他默认值。

在app控制器中设置助手和回调方法:

 # application_controller.rb class ApplicationController < ActionController::Base protect_from_forgery helper_method :current_user private def current_user @current_user ||= User.find(session[:user_id]) if session[:user_id] end def authenticate_user! unless current_user redirect_to root_url end end end 

before_filter放入受限制的控制器中以捕获未经授权的人员:

 # dashboard_controller.rb class DashboardController < ActionController::Base before_filter :authenticate_user! def index end # rest of controller here end 

将这两项添加到路线中。 如果不满足条件,则不会执行第一个。 如果是,则顶部优先,所有root_url调用将转到仪表板

 # routes.rb YourAppName::Application.routes.draw do root :to => 'dashboard#index', :conditions => lambda{ |req| !req.session["user_id"].blank? } root :to => 'static_page#index' # the rest of your routes end 

我认为你的解决方案比必要的更复杂。 为什么不在登录表单发布到的操作上执行这样简单的操作:

 def login // logic to check whether login credentials authorize user to sign in // say 'user_signed_in?' is boolean to determine whether user has successfully signed in redirect_to(user_signed_in? ? dashboard_path : root_path) end 

登录表单是在每个页面(顶部/侧边栏)上还是您有登录页面?

如果在每个页面上,您可以使用request.referrer来了解用户来自何处。

您可以使用应用程序控制器上的before_filter来控制它。

我不确定你是否在某个地方使用after_filter或before_filter进行重定向,但是你可以在登录控制器中使用skip_filter。 然后将自定义重定向作为该控制器中的filter。

在Rails中跳过before_filter