更有效的 rails 方法来检查三个字段中的任何一个是否是唯一的?

More efficient, rails way to check for any of three fields being unique?

因此,我需要在创建对象之前检查三个字段的唯一性(从表单),但只要这三个字段中的任何一个是唯一的,我就会创建对象。

我的第一个想法是将参数从控制器传递到模型,然后 运行 查询以检查是否具有这三个字段的查询 returns > 0 文档。但是,我后来了解到这是一种危险的方法,不应使用。

所以我检查了 the docs,并基于这个片段

Or even multiple scope parameters. For example, making sure that a teacher can only be on the schedule once per semester for a particular class.

class TeacherSchedule < ActiveRecord::Base
  validates_uniqueness_of :teacher_id, scope: [:semester_id, :class_id]
end

我以为我找到了答案,并实施了:

validates_uniqueness_of :link_to_event, :scope => [:name_of_event, :date_of_event]

有效!但是,这个数据集会变得非常大(不仅仅是这个表单,大声笑),而且我的印象是,通过这个实现,Rails 将查询所有带有 [=28= 的字段],然后是 name_of_event 的所有字段,然后是 date_of_event 的所有字段。所以,我的问题是:

A) 我对 rails 将如何实施这一点的理解有误吗?开箱即用会更有效率吗?

B) 如果这对于具有几百万个条目的 table 来说效率不高,是否有更好的(并且仍然 railsy)方法来做到这一点?

您可以定义一个方法来查询包含您希望唯一的所有字段的记录:

validate :uniqueness_of_teacher_semester_and_class



def uniqueness_of_teacher_semester_and_class
  users = self.class.where(teacher_id: teacher_id, semester_id: semester_id, class_id: class_id)

  errors.add :base, 'Record not unique.' if users.exists?
end

回答您的问题:

A) Am I wrong about how rails will implement this? Is it going to be more efficient out of the box?

我认为 Rails 将查询所有 3 个字段的匹配项,您应该检查 Mongo(或 Rails)日志以确保确定。

B) If this will not be efficient for a table with a couple million entries, is there a better (and still railsy) way to do this?

这是Rails方式。您可以做两件事来提高效率:

  1. 您将需要所有 3 个字段的索引,或 3 个字段的复合索引。复合索引*可能*更快,但您可以进行基准测试以找出答案。

  2. 您可以添加一个新字段,将 3 个字段连接起来,并在其上添加索引。但是这样会占用额外的space,而且可能不会比复合索引快

如今,几百万个文档并不算多,但取决于文档大小和硬件。