设计 – 为多个用户单一登录表单

我有两个Devise模型,User和Business; 我希望两者都能够使用单一登录forms登录。 我正在使用骨干js,我有一个自定义的视图,所以视图不是一个问题。 ajax请求用于登录,它按预期适用于用户,但不适用于企业。

我搜索过谷歌,并提到了一些使用STI来解决这个问题的解决方案,但是项目已经完成了很多工作,我现在无法做出这样的改变。 我正在考虑重写Devise会话控制器和:

  1. 检查给定的电子邮件地址是否为用户,然后使用Warden对用户进行身份validation。
  2. 如果未找到具有该电子邮件的用户,则使用Warden对Business模型进行身份validation。

我无法弄清楚如何更改代码来实现上述目标,我不知道warden如何工作以及我需要调整哪些params来实现上述function,需要调用哪些函数。 任何人都可以指出我正确的方向或提供一个例子,说明我应该如何向前推进。

谢谢。

别担心,你不会被卡住。

我认为你最好的选择是覆盖Devise的会话控制器并改变会话的’new’和’create’方法。

所以在你自己的“sessions_controller.rb”中,你会有这样的东西:

class SessionsController < Devise::SessionsController # GET /resource/sign_in def new resource = build_resource(nil, :unsafe => true) clean_up_passwords(resource) respond_with(resource, serialize_options(resource)) end # POST /resource/sign_in def create resource = warden.authenticate!(auth_options) set_flash_message(:notice, :signed_in) if is_navigational_format? sign_in(resource_name, resource) respond_with resource, :location => after_sign_in_path_for(resource) end end 

在你的路线中,你会使用类似的东西(取决于你命名的用户模型):

 devise_for :users, :controllers => { :sessions => 'sessions' } devise_for :businesses, :controllers => { :sessions => 'sessions' } 

以上会话控制器根本不是自定义的。 我不知道你的代码,所以我无法真正帮助那里。 但基本步骤是:

  1. 检查auth_optionsresource_name变量以了解它们如何存储数据。
  2. 如果在Users表中找不到resource则添加条件逻辑以更改这些变量。

设计是伟大的,角色很棒,但有时候有一个用户模型,甚至使用STI,没有意义。 我很快就在这个问题上写了一篇更长的post,因为我在最近的一个项目中处理了这个问题。

请考虑仅使用User模型并使用CanCan和Rolify来满足每种类型用户的独特需求。 这可能意味着从一些代码开始,但从长远来看可能更容易维护。

不要只听我的话。 这是一个有良好反应的相关问题。

我最近想出了这个完全黑客来完成这项工作。 我的建议是强烈考虑具有角色的单个用户模型,但这是有效的 – 至少对于当前版本的Devise。

https://gist.github.com/jeremyw/5319386

如果你monkeypatch或以其他方式覆盖这样的默认行为,请确保你有一个好的测试套件,以防你想尝试升级Devise。