email
和new_email
是两个不同的列。每封电子邮件都应该是唯一的,因此,如果在任一列中添加了电子邮件,则该邮件在email
或new_email
列中都不会存在。
背景故事:我为已激活的帐户创建了主要email
,并在用户决定更改其电子邮件地址但尚未通过电子邮件确认验证新电子邮件地址时设置第二个new_email
。
大多数SO搜索都提供了scope
solution:
我已经尝试validates :email, uniqueness: {scope: :new_email}
和validates :new_email, uniqueness: {scope: :email}
但是我很确定此功能会在email1, email2
对中创建一个新密钥,而这不是预期的效果。
目前,我正在使用以下两个测试用例(失败)来判断我的代码的有效性。
test "new_email should not match old email" do
@user.new_email = @user.email
assert_not @user.valid?
end
test "new_email addresses should be unique" do
duplicate_user = @user.dup
duplicate_user.new_email = @user.email.upcase
duplicate_user.email = @user.email + "z"
@user.save
assert_not duplicate_user.valid?
end
答案 0 :(得分:0)
我认为你真的只想写一个自定义验证器,如下所示:
validate :emails_are_unique
def emails_are_unique
if email == new_email
errors.add(:base, 'Your new email can not match your old email')
end
end
哪个会做你想要的。
答案 1 :(得分:0)
范围不会削减它...确实mail
在所有可能共享相同new_mail
并赢得&#的记录中是唯一的39; t捕获不同new_email
值的唯一性,也不比较两列中的值。
使用标准'唯一性'确保列中没有重复。
然后您需要为交叉列创建自定义验证...
validate :emails_unique
def emails_unique
found_user = User.find_by(new_email: email)
errors.add(:email, "email is someone's new email") if found_user
return unless new_email
found_user = User.find_by(email: new_email)
errors.add(:new_email, "new email is someone's regular email") if found_user
end
答案 2 :(得分:0)
validates :email, uniqueness: {scope: :new_email}
将确保email
在new_email
具有相同值的所有记录中是唯一的。这不是你想要的。
您必须编写自定义验证功能,例如:
def validate_email_and_new_email_unique
if email && self.class.exists?("email = :email OR new_email = :email", email: email)
errors.add :email, "must be unique"
end
if new_email && self.class.exists?("email = :email OR new_email = :email", email: new_email)
errors.add :new_email, "must be unique"
end
end