我有一个ActiveRecord对象,公司,我的项目中唯一一个创建此对象实例的调用如下:
corp = Corporation.find_or_create_by_eveid_and_user_id(self.corporation_eveid, self.account.user_id)
然而不知何故,在我的应用程序快乐地运行了几天后,有重复的记录 - 记录eveid和user_id具有相同的值。这怎么可能?在我更新这些会导致此问题的记录的方式中,我可能做错了吗?
我最终为表添加了一个唯一的复合索引。这应该可以解决问题,但我不明白它是如何发生的。
这是Rails 3.0.7。
答案 0 :(得分:5)
find_or_create
不会执行任何锁定,也不会尝试阻止竞争条件。这只是一种方便的方法。如果竞争条件有问题,您需要:
SELECT ... FOR UPDATE
。如果您没有锁定参考点(即没有外键或数据库中已存在的任何东西),那么您将不得不坚持使用(1)。编辑|如果您可以在架构级别添加UNIQUE约束,我建议也这样做,如果这是一个真正的完整性问题。
答案 1 :(得分:0)
这是你的种子档案吗?您最好的选择是在模型中编写验证,以防止公司与eveid和user_id相同。
在我看来,你使用find_or_create播种了这些信息。但是可能在当天或之后的某天晚些时候,有人使用您的GUI创建了另一个具有相同信息的人。验证会阻止这种情况。
我没有测试过这段代码,但是这样的代码可能适合你。
validates :eveid, :uniqueness => { :scope => :user_id }