[英]Rails cross model validation
我有兩個表一個用於成員,另一個用於員工,兩個表都有一個名為id_number
的屬性,這個屬性不是必需的,可以為null。
是否可以運行驗證以確保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添加一個索引會很好。
更新:上述方法可以更改為以下方法以提高性能:
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服務器實例,則這些類型的rails side check不能100%保證唯一性,因為它們會受到線程之間的競爭。 在這種情況下確保唯一性的唯一方法是使用數據庫中內置的工具,或者從排除重復項的源(例如數據庫序列)自己生成id_numbers。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.