Rails,Devise:相同的资源,基于用户类型的不同控制器

我有一个资源,比如Product ,可以通过两个不同的用户类访问:比如CustomerAdmin 。 这两者之间没有inheritance。

我正在使用Devise进行身份validation:

 # config/routes.rb devises_for :customers deviser_for :admins 

我有这两个控制器:

 # app/controllers/customers/products_controller.rb class Customers::ProductsController < ApplicationController 

 # app/controllers/admins/products_controller.rb class Admins::ProductsController < ApplicationController 

现在,根据谁登录( CustomerAdmin ),我希望products_path指向相应的控制器。 我想避免使用customers_products_pathadmins_products_path ,这很麻烦。

所以我已经设置了我的路线

 # config/routes.rb devise_scope :admin do resources :products, module: 'admins' end devise_scope :customer do resources :products, module: 'customers' end 

这不起作用。 当我以Customer身份登录时, products_path仍然指向Admins::ProductsController#index因为它是第一个定义的。

任何线索? 没有黑客行为,我想做的事情可能根本不可能。

更新根据代码 ,它是不可行的。

事实certificate,实现这一目标的最佳方法是使用路由约束:

 # config/routes.rb resources :products, module: 'customers', constraints: CustomersConstraint.new resources :products, module: 'admins', constraints: AdminsConstraint.new # app/helpers/customers_constraint.rb class CustomersConstraint def matches? request !!request.env["warden"].user(:customer) end end # app/helpers/admins_constraint.rb class AdminsConstraint def matches? request !!request.env["warden"].user(:admin) end end 

我将约束对象存储在帮助文件夹中,因为我真的不知道放置它们的最佳位置。

感谢@crackofdusk提示。

为此,您需要覆盖现有的after_sign_in_path_for设计方法。 把它放在你的app/controllers/application_controller.rb

 def after_sign_in_path_for(resource) if resource.class == Admin '/your/path/for/admins' elsif resource.class == Customer '/your/path/for/customers' end end 

注意 :如果要实现用户请求的previous_url ,则可以像下面这样使用它:

  session[:previous_url] || 'your/path/for/admins'