我有两个表,一个用于成员,另一个用于员工,两个表都有一个名为id_number
的属性,此属性不是必需的,可以为null。Rails跨模型验证
是否有可能运行验证,以确保所述的id_number
的唯一性,所以,如果一个雇员中加入相同id_number
作为构件,或反之亦然,这将给出一个错误。
我正在考虑编写自己的验证,但是每个实例的db都会很慢,因为有些公司每次上传数以十万计的员工。
我有两个表,一个用于成员,另一个用于员工,两个表都有一个名为id_number
的属性,此属性不是必需的,可以为null。Rails跨模型验证
是否有可能运行验证,以确保所述的id_number
的唯一性,所以,如果一个雇员中加入相同id_number
作为构件,或反之亦然,这将给出一个错误。
我正在考虑编写自己的验证,但是每个实例的db都会很慢,因为有些公司每次上传数以十万计的员工。
是的,这可能与您自己的验证。我认为你必须击中数据库,否则你永远无法检查它是否已经存在。
def your_validation
employee_ids = Employee.all.map(&:id_number)
member_ids = Member.all.map(&:id_number)
id = self.id_number
if employee_ids.include?(id) || member_ids.include?(id)
errors.add(:id_number, "is already taken")
end
end
我想为你的id_number添加一个索引会很好。
UPDATE:上述方法可以被改变成以下以提高性能:
def your_validation
employee_ids = Employee.all.map(&:id_number)
if employee_ids.include?(self.id_number)
errors.add(:id_number, "is already taken")
else
member_ids = Member.all.map(&:id_number)
if member_ids.include?(self.id_number)
errors.add(:id_number, "is already taken")
end
end
end
第一个是清洁器,第二个要快。但请查看大量数据库条目和基准测试工具。
我想你会想是这样的:
def your_validation
if self.id_number.present?
if Employee.exists?(:id_number=>self.id_number) || Member.exists(:id_number=>self.id_number)
errors.add(:id_number, "is already taken")
end
end
end
,如果你对ID_NUMBER列此检查应该非常快速运行指标和相同的支票,validates_uniqueness_of将一个表中使用。当表格变大时,涉及将所有id提取到rails的解决方案将开始遇到问题。
要注意的另一件事是,如果您的应用程序一次运行多个Web服务器实例,这些类型的边检不能100%保证唯一性,因为它们受线程间的竞争影响。在这种情况下确保唯一性的唯一方法是使用内置于数据库中的设施,或者使用排除重复项(例如数据库序列)的来源自行生成id_numbers。
是的,我认为添加一个索引会显着加快速度。它看起来与我正在抨击的那个相似。唯一的事情是我相信你的工作哈哈。谢谢你,这是完美的 – TheLegend
你可以改变employee_ids.include的顺序吗?和member_ids包括?...这可以提高速度,如果你有更多的成员比员工条目和vica,因为如果第一个已经找到新的id_number其他情况下永远不会执行。我会尽快更新我的答案。 – Mattherick