Rails:在单个表继承中使用Devise

| 我在使Devise以单表继承的方式工作时遇到问题。 我有两种不同类型的帐户,其组织如下:
class Account < ActiveRecord::Base
  devise :database_authenticatable, :registerable
end

class User < Account
end

class Company < Account
end
我有以下路线:
devise_for :account, :user, :company
用户在
/user/sign_up
注册,公司在
/company/sign_up
注册。所有用户都以form4ѭ(
Account
是父类)的单一表单登录。 但是,通过这种形式登录似乎只能对“ 5”作用域进行身份验证。随后对诸如“ 7”或“ 8”之类的动作的请求将用户引导至相应范围的登录屏幕。 如何让Devise识别帐户“类型”并针对相关范围进行身份验证? 任何建议,不胜感激。     
已邀请:
我只是遇到了问题中概述的确切场景(类名已更改)。这是我的解决方案(Devise 2.2.3,Rails 3.2.13): 在config / routes.rb中:
devise_for :accounts, :controllers => { :sessions => \'sessions\' }, :skip => :registrations
devise_for :users, :companies, :skip => :sessions
在app / controllers / sessions_controller.rb中:
class SessionsController < Devise::SessionsController
    def create
        rtn = super
        sign_in(resource.type.underscore, resource.type.constantize.send(:find, resource.id)) unless resource.type.nil?
        rtn
    end
end
注意:由于您的Accounts类仍然是:registerable的,因此会尝试发出views / devise / shared / _links.erb中的默认链接,但是new_registration_path(Accounts)将不起作用(我们在路线图中跳过)并导致错误。您将必须生成设计视图并手动将其删除。 提示https://groups.google.com/forum/?fromgroups=#!topic/plataformatec-devise/s4Gg3BjhG0E,以向我指出正确的方向。     
在路由中有一种简单的方法可以处理STI。 假设您具有以下STI模型:
def Account < ActiveRecord::Base
# put the devise stuff here
devise :database_authenticatable, :registerable,
    :recoverable, :rememberable, :trackable, :validatable
end

def User < Account
end

def Company < Account
一个经常被忽略的方法是,您可以在routes.rb文件中的经过身份验证的方法中指定一个块:
## config/routes.rb

devise_for :accounts, :skip => :registrations
devise_for :users, :companies, :skip => :sessions

# routes for all users
authenticated :account do
end

# routes only for users
authenticated :user, lambda {|u| u.type == \"User\"} do
end

# routes only for companies
authenticated :user, lambda {|u| u.type == \"Company\"} do
end
要获取各种帮助程序方法,例如\“ current_user \”和\“ authenticate_user!\”(已经定义了\“ current_account \”和\“ authenticate_account!\”),而不必为每个方法定义单独的方法(此方法很快变得难以维护)随着添加更多用户类型),您可以在ApplicationController中定义动态帮助器方法:
## controllers/application_controller.rb
def ApplicationController < ActionController::Base
  %w(User Company).each do |k| 
    define_method \"current_#{k.underscore}\" do 
        current_account if current_account.is_a?(k.constantize)
    end 

    define_method \"authenticate_#{k.underscore}!\" do 
    |opts={}| send(\"current_#{k.underscore}\") || not_authorized 
    end 
  end
end
这就是我解决导轨设计STI问题的方法。     
我认为如果不重写会话控制器,这是不可能的。每个sign_in页面都有一个特定的范围,该范围将根据您的路由定义进行验证。 通过在路由文件中使用devise_scope函数强制:users和:companies都使用同一登录页面,可以在多个用户范围内使用相同的sign_in页面(方法可在此处找到),但是我敢肯定,您必须修改会话控制器以执行一些自定义逻辑,才能确定登录的用户类型。     
尝试像这样更改路线: devise_for:帐户,:用户,:companies 因为Devise使用复数名称作为其资源 请告诉我是否对您有帮助     

要回复问题请先登录注册