Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 添加唯一性:值只能在两个表中的四列上出现一次_Ruby On Rails_Ruby_Postgresql_Validation_Ruby On Rails 4 - Fatal编程技术网

Ruby on rails 添加唯一性:值只能在两个表中的四列上出现一次

Ruby on rails 添加唯一性:值只能在两个表中的四列上出现一次,ruby-on-rails,ruby,postgresql,validation,ruby-on-rails-4,Ruby On Rails,Ruby,Postgresql,Validation,Ruby On Rails 4,我有两个表:users和members(它们代表两种类型的用户)。这两个表包括两列:email和new\u email。我希望在模型和迁移文件中进行验证,以便电子邮件地址只能在这四列中存在一次(因此不是在每列中都存在一次,而是在所有四列中都存在一次)。如何实现这一点?到目前为止,我已经: 1.成员模型(还包括用户模型文件): 我认为scope::new_email是一个不正确的实现。我认为这测试的是两列之间组合的唯一性,而不是组合的两列中值的唯一性? 客户验证器是否合适?也就是说,将行添加到pr

我有两个表:users和members(它们代表两种类型的用户)。这两个表包括两列:
email
new\u email
。我希望在模型和迁移文件中进行验证,以便电子邮件地址只能在这四列中存在一次(因此不是在每列中都存在一次,而是在所有四列中都存在一次)。如何实现这一点?到目前为止,我已经:

1.成员模型(还包括用户模型文件):

我认为
scope::new_email
是一个不正确的实现。我认为这测试的是两列之间组合的唯一性,而不是组合的两列中值的唯一性?
客户验证器是否合适?也就是说,将行添加到private方法中(在成员表中检查,与在用户表中检查相同):

2.成员迁移:

  t.string   :new_email
  t.datetime :activation_sent_at

  add_index :members, [:email, :new_email], unique: true
不确定如何在迁移文件中包含超过一列的唯一性,即所有四列的唯一性。在当前的实施中,我认为只检查电子邮件和新电子邮件的组合,而根本不查看其他表格。


更新:我想更大的问题是如何实现我想要实现的目标。我现在想,不验证新电子邮件的唯一性可能更容易。相反,当用户单击确认链接,应用程序希望用
新电子邮件
覆盖
电子邮件时,此时将应用唯一性验证。这是一种更合适的实现方式吗?

我的新电子邮件的基本原理:如果用户/成员想要更改其电子邮件地址,新地址最初存储在那里。确认后会覆盖
电子邮件
。这有意义吗?或者这通常是以不同的方式进行的?这个想法是:如果用户/会员拼错了他的新电子邮件地址怎么办。如果它将立即覆盖
电子邮件
,则该用户将无法再访问其帐户。这是如何“正常”实现的?那么您的意思是将
范围:[:new\u email,:email]
添加到模型文件中?这不是只验证这两列中值的唯一组合的唯一性吗?而不是唯一的值,无论该值是否在
电子邮件
新电子邮件
的列中?另外,你知道我应该在迁移文件中做什么吗?我想你是对的,这就是
scope
的工作原理。您可以合并查询以检查电子邮件,如
。where((?),[self.email.downcase,self.new\u email.downcase])
,这将有助于加快速度。根据您的数据库引擎,您可能无法在2列上强制唯一性。你在用什么?谢谢,我按照建议重构了我原来的帖子。我正在使用PostgreSQL。例如,如果我将其与Twitter进行比较,我的理由是类似的:您提供了一个新的电子邮件地址,但旧的电子邮件地址仍然是使用中的电子邮件地址,只要新的电子邮件地址尚未确认。您可以添加一个
检查
约束,类似于
检查(电子邮件不在新电子邮件中)
我不确定这是否有效,我找不到在
检查中使用
in
操作符的任何示例,我也不知道您将如何通过迁移添加此操作。
  if self.where("lower(email) in (?)", [self.email.downcase, self.new_email.downcase]).first
    errors.add(:email, "There is already a user with this email address")
  t.string   :new_email
  t.datetime :activation_sent_at

  add_index :members, [:email, :new_email], unique: true