Rails 4 设计,after_sign_in_path_for(资源) 总是重定向到模型的显示操作
Rails 4 Devise, with after_sign_in_path_for(resource) always redirect to Show action of Model
我坚持使用设计方法 after_sign_in_path_for,这就是问题所在...
我有两个模型 Users 和 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
好的...在我的 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
如您所见,我有一些 puts 只是为了在我的控制台中检查我的 case 是否有效...确实如此,它确实有效,这是我的控制台:
我正在尝试以 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 的显示页面。
如果我尝试以用户身份登录,控制台如下:
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 都在做同样的事情...重定向到每个模型的显示操作,我已经尝试将此代码放在自定义 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
请试试这个:
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
我认为这是问题中的错字,而不是代码中的错字(因为它打印的是 puts)。其次,after_sign_in_path
必须 return 一个 url,并且您的代码的最后一个操作是 puts
,即 return 和 nil
。
你也可以试试:
def after_sign_in_path_for(resource)
dashboard_index_path
end
第一次看到 after_sign_in_path_for
工作。并以此为起点向前迈进。
如果这一切都不起作用,请发布 sign_in
和 login
路线。
编辑:在阅读了您的 post 之后,我意识到这种情况不起作用(错误:有效),因为这种情况与 ===
一起使用并且resource.class === AdminUser
总是 return false(是不同的对象)。您必须要求 resource.class == AdminUser
或 resource.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
值作为对象,case 值作为参数。在这种情况下,第一个 when 子句用 User.===(resource)
或 User === resource
测试,第二个用 AdminUser.===(resource)
测试。由于 User
和 AdminUser
是 Class 对象,因此它们使用 Module#===
method。这里重要的是要注意这个方法是不可交换的,它是一个接受任何对象作为参数的 class 方法,如果参数是 class 的实例,则 return 为真.
非常感谢亚历杭德罗,
你对我的 puts 错误是正确的,实际上我对 return 如此明显的错误感到尴尬的方法...
由于一些我不知道案例不起作用的奇怪原因......它对 AdminUser 模型有效,但对 User[=23= 无效] 模型...如果有人有想法,请告诉我,因为我讨厌有疑问的状态,并且知道我没有时间解决...
我对代码做了这个小改动,对我有用...我知道这是一个难看的代码,但它完成了工作,也许以后我有时间制作更好的代码。
def after_sign_in_path_for(resource)
return dashboard_index_path if resource.class == User
return admin_root_path
end
非常感谢!
我坚持使用设计方法 after_sign_in_path_for,这就是问题所在... 我有两个模型 Users 和 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
好的...在我的 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
如您所见,我有一些 puts 只是为了在我的控制台中检查我的 case 是否有效...确实如此,它确实有效,这是我的控制台: 我正在尝试以 AdminUser 身份登录到 active_admin
的 admin_root_pathStarted 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 的显示页面。
如果我尝试以用户身份登录,控制台如下:
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 都在做同样的事情...重定向到每个模型的显示操作,我已经尝试将此代码放在自定义 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
请试试这个:
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
我认为这是问题中的错字,而不是代码中的错字(因为它打印的是 puts)。其次,after_sign_in_path
必须 return 一个 url,并且您的代码的最后一个操作是 puts
,即 return 和 nil
。
你也可以试试:
def after_sign_in_path_for(resource)
dashboard_index_path
end
第一次看到 after_sign_in_path_for
工作。并以此为起点向前迈进。
如果这一切都不起作用,请发布 sign_in
和 login
路线。
编辑:在阅读了您的 post 之后,我意识到这种情况不起作用(错误:有效),因为这种情况与 ===
一起使用并且resource.class === AdminUser
总是 return false(是不同的对象)。您必须要求 resource.class == AdminUser
或 resource.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
值作为对象,case 值作为参数。在这种情况下,第一个 when 子句用 User.===(resource)
或 User === resource
测试,第二个用 AdminUser.===(resource)
测试。由于 User
和 AdminUser
是 Class 对象,因此它们使用 Module#===
method。这里重要的是要注意这个方法是不可交换的,它是一个接受任何对象作为参数的 class 方法,如果参数是 class 的实例,则 return 为真.
非常感谢亚历杭德罗,
你对我的 puts 错误是正确的,实际上我对 return 如此明显的错误感到尴尬的方法... 由于一些我不知道案例不起作用的奇怪原因......它对 AdminUser 模型有效,但对 User[=23= 无效] 模型...如果有人有想法,请告诉我,因为我讨厌有疑问的状态,并且知道我没有时间解决...
我对代码做了这个小改动,对我有用...我知道这是一个难看的代码,但它完成了工作,也许以后我有时间制作更好的代码。
def after_sign_in_path_for(resource)
return dashboard_index_path if resource.class == User
return admin_root_path
end
非常感谢!