是否有Rails Gem Devise的解决方案允许用户拥有多封电子邮件?
我正在寻找一种解决方案,允许我的应用上的用户拥有超过1封电子邮件。 这应该类似于Facebook,LinkedIn和Quora。 帐户可以有多封电子邮件,1为主要邮件。
是否有设计的交钥匙解决方案? 我希望不必从头开始写这个,因为它很常见。
想法? 谢谢
嗯…我建议创建新模型,你会做这样的事情:
例如,模型是UserEmail
。
class UserEmail < ActiveRecord::Base belongs_to :user end class User < ActiveRecord::Base has_many :user_emails end
并覆盖设备在User
模型中查找记录的方法:
def self.find_first_by_auth_conditions(warden_conditions) conditions = warden_conditions.dup if email = conditions.delete(:email) User.includes(:user_emails).where('user_emails.email = ?', email).first else super(warden_conditions) end
阅读更多关于覆盖的信息: https : //github.com/plataformatec/devise/wiki/How-To : -Allow-users-to-sign-in-using-their-username-or-email-address
鲍勃的答案很接近,但它有一个潜在的危险错误。 find_first_by_auth_conditions
方法应如下所示:
def self.find_first_by_auth_conditions(warden_conditions) conditions = warden_conditions.dup if email = conditions.delete(:email) User.includes(:user_emails).where('user_emails.email = ?', email).first else super(warden_conditions) end end
电子邮件检查和调用super
很重要,因为Devise也使用此方法通过confirmation_token
, unlock_token
和reset_token
查找User
。 如果没有else分支,对此方法的任何没有email
参数的调用都将失败,或者使用nil
电子邮件加载用户。
我建议你创建一个新的模型SecondaryEmail
。
User
可以has_many :secondary_emails
,每个SecondaryEmail
belongs_to :user
。
您必须为SecondaryEmail
每封电子邮件添加唯一性validation,此外,还必须确保没有新的SecondaryEmail已经是任何用户的主电子邮件。
提供界面,以便User
可以使用这些validation添加他的secondary_emails。
下一步将覆盖Devise的SessionController
。
在任何登录过程中,只要在用户的主电子邮件中找不到电子邮件, SecondaryEmail.where(:email => params[:email])
以为SecondaryEmail.where(:email => params[:email])
设置登录过程。 如果存在,则使用该用户的密码进行身份validation,否则用户不存在。
这是我到目前为止所提出的。 我真的很想知道专家的观点和方法。 🙂
我前一段时间遇到过这个问题 – 并在我的博客中概述了解决方案。
步骤总结如下:
- 电子邮件信息必须存储在其他模型中,例如
Email
。 因此,User
有许多相关的Email
实例。 - 我们很可能希望将一封电子邮件指定为默认电子邮件,我们可以将其用于与用户进行通信。
-
User
类find_first_by_auth_conditions
的类方法用于查找提供的凭据的用户 – 因此我们必须覆盖该方法以使用Email
模型进行搜索。 - 我们将不得不更改默认视图,因为它们隐含地假设存在用户的
email
方法。 我们可以使用添加代理访问器来代替用户的默认电子邮件,而不是完全重写视图。 - 如果允许用户拥有多封电子邮件 – 我们还希望在帐户编辑页面中提供用户工具来添加/删除电子邮件。
- 如果您需要omniauth集成 – 那么必须修改设计维基中概述的
User.from_omniauth
的库存实现以支持多个电子邮件。
我的实现可以在Github上找到 。
这里给出的答案非常好,应该可以解决您的问题。 为了回答你的上一个问题,我认为你不会为此找到一个gem,因为它太简单了,即使它很常见。 只是按照建议从头开始,它应该不是很多工作:)
鲍勃的回答在rails 4.1.5中为我提出了一个SQL错误 – 根据http://guides.rubyonrails.org/active_record_querying.html#specifying-conditions-on-eager-loaded-associations ,下面的更改使其工作正常:
def self.find_first_by_auth_conditions(warden_conditions) conditions = warden_conditions.dup if email = conditions.delete(:email) User.includes(:user_emails).where(user_emails: {email: email}).first else super(warden_conditions) end end
您可以使用devise-multi_email gem: https : //github.com/allenwq/devise-multi_email
替换devise :multi_email_authenticatable
devise :authenticatable
devise :multi_email_authenticatable
,以便您的模型可能如下所示:
class User < ActiveRecord::Base has_many :emails # Replace :database_authenticatable, with :multi_email_authenticatable devise :multi_email_authenticatable, :registerable end class Email < ActiveRecord::Base belongs_to :user end
如果您希望所有电子邮件都可以确认并从您的任何电子邮件中恢复您的密码,那么就是
devise :multi_email_authenticatable, :multi_email_confirmable, :confirmable