我正在寻找一种解决方案,允许我的应用上的用户拥有超过1封电子邮件。这应该类似于Facebook,LinkedIn和Quora。帐户可以有多封电子邮件,1为主要邮件。
是否有设计的交钥匙解决方案?我希望不必从头开始写这个,因为它很常见。
想法?感谢
答案 0 :(得分:15)
嗯...我建议创建新模型,你会做这样的事情:
例如,模型为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
答案 1 :(得分:8)
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
,confirmation_token
和{{1}之间查找unlock_token
}。如果没有else分支,对此方法的任何没有reset_token
参数的调用都将失败,或者使用email
电子邮件加载用户。
答案 2 :(得分:4)
我建议你创建一个新模型SecondaryEmail
User
可以has_many :secondary_emails
,每个SecondaryEmail
belongs_to :user
。
您必须在SecondaryEmail
中为每封电子邮件添加唯一性验证,此外,还必须确保没有新的SecondaryEmail已经是任何用户的主要电子邮件。
提供界面,以便User
可以使用这些验证添加他的secondary_emails。
下一步将覆盖设计<{strong>的SessionController
在任何登录过程中,只要在用户的主要电子邮件中找不到电子邮件,就设置SecondaryEmail.where(:email => params[:email])
的登录过程。如果存在,则使用该用户的密码进行身份验证,否则用户不存在。
这是我到目前为止所提出的。我真的很想知道专家的观点和方法。 :)
答案 3 :(得分:3)
我前一段时间遇到过这个问题 - 并在my blog中概述了解决方案。
步骤总结如下:
Email
。因此,User
有许多相关的Email
个实例。User
类find_first_by_auth_conditions
的类方法用于查找提供的凭据的用户 - 因此我们必须覆盖该方法以使用Email
模型进行搜索。email
用户方法。我们可以使用添加代理访问器来代替用户的默认电子邮件,而不是完全重写视图。User.from_omniauth
的库存实现以支持多封电子邮件。我的实施可用on Github。
答案 4 :(得分:1)
这里给出的答案非常好,应该可以解决您的问题。要回答你的上一个问题,我认为你不会为此找到一个宝石,因为它太简单了,即使它很常见。只是按照建议从头开始,它应该不是很多工作:)
答案 5 :(得分:1)
鲍勃的回答在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
答案 6 :(得分:0)
您可以使用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