Rails 4 Devise,after_sign_in_path_for(资源)总是重定向到Show的Model模型

时间:2015-04-14 17:01:16

标签: ruby-on-rails ruby devise

我坚持使用设计的post_sign_in_path_for方法,这就是...... 我有两个模型用户 AdminUsers 我正在使用 active_admin gem

我的 routes.rb 文件,如下所示:

devise_for :admin_users, ActiveAdmin::Devise.config
  ActiveAdmin.routes(self)
scope "(:locale)", locale: /es|en/ do
        devise_for :users, path_names: { sign_in: 'login', sign_out: 'logout', 
                                    password: 'password', confirmation: 'confirmation', unlock: 'unlock', 
                                    registration: 'registration', sign_up: 'sign_up' }
    devise_scope :user do
      get "login", to: "devise/sessions#new"
    end
get 'dashboard/index'
end

OK ...在我的application_controller.rb中,我尝试了这些代码:

def after_sign_in_path_for(resource)
      case resource
          when AdminUser
            #admin_root_path 
            '/admin/dashboard'
            puts'in admin_root_path'
          when User 
            #dashboard_index_path 
            '/dashboard/index'
            puts'in dashboard_index_path'
        else super
        end
      puts 'resource Of AplicationController: ' + resource.class.to_s

  end

  def after_sign_out_path_for(resource_or_scope)
    root_path
  end

正如你所看到的,我有一些 put 只是为了检查我的控制台,如果我的案例有效......而且确实如此,它确实有效,这是我的安慰: 我正在尝试以 AdminUser 的身份登录到active_admin的 admin_root_path

Started POST "/admin/login?locale=es" for ::1 at 2015-04-14 12:46:51 -0400
Processing by ActiveAdmin::Devise::SessionsController#create as HTML
....
....
in admin_root_path
resource of AplicationController: AdminUser
Redirected to http://localhost:3000/admin/users/2?locale=es
Completed 302 Found in 113ms (ActiveRecord: 1.8ms)

如您所见,Devise将我重定向到current_admin_user的Show页面。

如果我尝试以用户身份登录,这是控制台:

Started POST "/es/users/login" for ::1 at 2015-04-14 12:51:18 -0400
Processing by Devise::SessionsController#create as HTML
...
...
in dashboard_index_path
resource of AplicationController: User
Redirected to http://localhost:3000/es/users/2
Completed 302 Found in 106ms (ActiveRecord: 1.4ms)

在两个场景中,Devise正在做同样的事情......重定向到每个Model的show动作,我已经尝试将这个代码放在自定义的registrations_controller.rb中并​​且相同...... 也许我错过了一些明显的东西,我不是Devise的专家,有没有人知道我做错了什么?

rake routes命令的相关结果

....
....
edit_admin_user_password GET   /admin/password/edit(.:format)                 active_admin/devise/passwords#edit

admin_root GET     /admin(.:format)    admin/dashboard#index
....
....
admin_dashboard GET  /admin/dashboard(.:format)    admin/dashboard#index
....
....
dashboard_index GET    (/:locale)/dashboard/index(.:format)   dashboard#index {:locale=>/es|en/}
root GET    /    visitors#index

2 个答案:

答案 0 :(得分:2)

请试试这个:

def after_sign_in_path_for(resource)
  if resource.class == AdminUser
    admin_root_path 
  elsif resource.class == User
    dashboard_index_path 
  end
end

要注意两件事:我使用resourse.class我认为这是问题中的拼写错误,而不是代码(因为它打印了put)。其次,after_sign_in_path必须返回一个网址,代码上的最后一个操作是puts,返回nil

你也可以尝试:

def after_sign_in_path_for(resource)
  dashboard_index_path 
end

要查看after_sign_in_path_for第一次工作。从这个起点向前迈进。

如果所有这些都无效,请发布sign_inlogin路线。

修改:在阅读完您的帖子后,我意识到这个案例并没有(错误:它有效),因为案例适用===resource.class === AdminUser总是返回假(是不同的对象)。您必须要求resource.class == AdminUserresource.is_a?(AdminUser)。更多案例匹配here。我还更新了after_sign_in_path方法。

编辑2 在阅读@CJBrew评论后,这些实验在irb:

(main) > pp = Person.first
=> "#<Person id: 1 ..."
(main) > pp === Person
=> false
(main) > Person === pp
=> true
(main) > case pp
(main) | when Person  
(main) |   'yes'
(main) | end  
=> "yes"

我可以说这段代码必须正常工作:

def after_sign_in_path_for(resource)
  case resource
  when User
    root_path
  when AdminUser
    admin_contexts_path
  end
end

因为case使用=== when值作为对象而案例值作为参数。在这种情况下,第一个when子句使用User.===(resource)User === resource进行测试,第二个使用AdminUser.===(resource)进行测试。由于UserAdminUser是Class对象,因此它们使用Module#=== method。这里重要的是要知道这个方法不是可交换的,它是一个接受任何对象作为param的类方法,如果param是该类的一个实例,则返回true。

答案 1 :(得分:0)

非常感谢亚历杭德罗,

你的 put 错误是正确的,实际上我对这个方法的 return 这样一个明显的错误感到尴尬... 出于某种原因,我不知道案例不起作用......它适用于 AdminUser 模型,但绝不适用于用户模型......如果有人有想法,请告诉我,因为我怀疑国家,并且知道我没有时间去解决......

我对代码进行了这么小的改动,并且对我有用......我知道这是一个硬而难的代码,但是它可以完成这项工作,也许以后我有时间制作更好的代码。

def after_sign_in_path_for(resource)
  return dashboard_index_path if resource.class == User
  return admin_root_path
end

非常感谢!