是否有Rails Gem Devise的解决方案允许用户拥有多封电子邮件?

时间:2013-04-29 17:50:05

标签: ruby-on-rails ruby-on-rails-3 devise

我正在寻找一种解决方案,允许我的应用上的用户拥有超过1封电子邮件。这应该类似于Facebook,LinkedIn和Quora。帐户可以有多封电子邮件,1为主要邮件。

是否有设计的交钥匙解决方案?我希望不必从头开始写这个,因为它很常见。

想法?感谢

7 个答案:

答案 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

在此处详细了解覆盖:https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address

答案 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也使用此方法在Userconfirmation_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个实例。
  • 我们很可能希望将一封电子邮件指定为默认电子邮件,我们可以将其用于与用户进行通信。
  • Userfind_first_by_auth_conditions的类方法用于查找提供的凭据的用户 - 因此我们必须覆盖该方法以使用Email模型进行搜索。
  • 我们必须更改默认视图,因为它们隐含地假设存在email用户方法。我们可以使用添加代理访问器来代替用户的默认电子邮件,而不是完全重写视图。
  • 如果允许用户拥有多封电子邮件,我们还希望在帐户编辑页面中提供添加/删除电子邮件的用户工具。
  • 如果您需要omniauth集成 - 那么必须修改设计维基中概述的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