【问题标题】:Validate uniqueness of email against another model's email address's根据另一个模型的电子邮件地址验证电子邮件的唯一性
【发布时间】:2014-09-21 01:18:02
【问题描述】:

我有一个用户模型,它有一个 "has_many" :emails 关联到一个电子邮件模型。用户的主电子邮件只是用户的“电子邮件”列。但是,我的这种关联允许一个用户使用多个电子邮件地址。

问题在于,当创建新用户并检查“validates_uniqueness_of :email”时,它只检查其他用户的电子邮件列,而不是电子邮件模型中存储的可能的辅助电子邮件。

我试图在我的用户模型中编写一个自定义验证方法,该方法试图通过给定的电子邮件地址找到用户并且它可以工作,但随后它在我的代码中搞砸了其他事情,比如能够添加辅助电子邮件地址或分配主要的。

有没有办法这样说:“validates_uniqueness_of :email through Email.all.each do {|e| errors.add :email, “this is invalid” if e.email == :email}”

这看起来真的很草率,但我要做的就是根据另一个模型实例的电子邮件地址在创建时验证用户电子邮件地址的唯一性。

附:如果您对 e.email 感到困惑,Email 是模型,它有一个 email 列来存储电子邮件地址。

【问题讨论】:

  • 用户模型中还需要email 字段的任何特殊原因?

标签: ruby-on-rails validation email associations


【解决方案1】:

听起来您需要稍微考虑一下您的架构。我会从您的User 模型中删除电子邮件列,而是使用关联存储所有电子邮件。您可以将default 标志添加到Email 模型以表示用户的默认电子邮件。这将允许您将validates_uniqueness_of :email 移动到Email 模型,而不是尝试在多个地方检查它。此外,它还会清理您的数据,使其不会出现在多个位置。

【讨论】:

  • 我们在不久前添加了这个功能,但是我们真的在做别的事情,所以我们现在不能回去真正花时间在它上面。在此期间我可以做一些快速修复吗?
  • 您可以添加一个before_save 钩子来检查另一个表是否具有相同的电子邮件,如果是,则返回 false 并向模型添加错误以使其不保存。
  • 我想我会试试 before_save 钩子。我有点想避免这种情况,因为它与验证器是分开的。
【解决方案2】:

您需要编写一个自定义验证器。大致如下:

class User 

  validates_uniqueness_of :email
  validate :email_in_use

  private

  def email_in_use
    if Email.where("lower(email) = ?", self.email.downcase).first
      errors.add(:email, "There is already a user with this email")
    end
  end

end

不过,我同意 @CWitty 的观点——您可能需要考虑将主电子邮件地址移动到“电子邮件”表中,而不是将其直接存储在用户模型中。

【讨论】:

  • 编写自定义验证器是我尝试的第一件事,但由于某种原因,它影响了添加辅助电子邮件地址的功能。
猜你喜欢
  • 2014-05-23
  • 1970-01-01
  • 2020-03-12
  • 1970-01-01
  • 1970-01-01
  • 2012-10-22
  • 2014-03-02
  • 2021-08-22
  • 2018-07-08
相关资源
最近更新 更多