我正在寻找一种解决方案,以允许我的应用程序上的用户拥有超过 1 封电子邮件。这应该类似于 Facebook、LinkedIn 和 Quora。一个帐户可以有多个电子邮件,其中 1 个作为主要电子邮件。
是否有可供设计的交钥匙解决方案?我希望不必从头开始写这个,因为它很常见。
想法?谢谢
我正在寻找一种解决方案,以允许我的应用程序上的用户拥有超过 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
Bob 的答案很接近,但它有一个潜在的危险错误。该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 也使用这种方法来查找User
s confirmation_token
、unlock_token
和reset_token
。如果没有 else 分支,对该方法的任何没有email
参数的调用都将失败,或者使用nil
电子邮件加载用户。
我建议你创建一个新模型SecondaryEmail
。
一个User
可以has_many :secondary_emails
,每个SecondaryEmail
belongs_to :user
。
您必须为 中的每封电子邮件添加唯一性验证SecondaryEmail
,并且还必须确保没有新的 SecondaryEmail 已经是任何用户的主要电子邮件。
提供接口,以便 aUser
可以使用这些验证添加他的 secondary_emails。
下一步将SessionController
覆盖Devise。在任何登录过程中,只要在用户的主要电子邮件中找不到电子邮件,就
设置您的登录过程。SecondaryEmail.where(:email => params[:email])
如果存在,则使用该用户的密码进行身份验证,否则,用户不存在。
这是我到目前为止想出的。我真的很想知道专家对此的看法和方法。:)
我不久前遇到了这个问题 - 并在我的博客中概述了解决方案。
步骤总结如下:
Email
. 所以 aUser
有很多相关的Email
实例。User
该类的类方法find_first_by_auth_conditions
用于查找用户提供的凭据 - 因此我们必须覆盖该方法才能使用Email
模型进行搜索。email
用户方法。我们可以使用为电子邮件添加代理访问器,而不是完全重写视图,以委托给用户的默认电子邮件。User.from_omniauth
必须修改设计wiki 中概述的库存实现以支持多个电子邮件。我的实现在 Github上可用。
Bob 的回答在 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 :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