Rails,Devise:相同的资源,基于用户类型的不同控制器
我有一个资源,比如Product
,可以通过两个不同的用户类访问:比如Customer
和Admin
。 这两者之间没有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
现在,根据谁登录( Customer
或Admin
),我希望products_path
指向相应的控制器。 我想避免使用customers_products_path
和admins_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'