作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
众所周知,Model.find_or_create_by(X)
实际上是这样做的:
并且步骤 1 和步骤 2 之间可能存在竞争条件。为了避免数据库中 X 的重复,应该在 X 的字段集上使用唯一索引。但是如果您应用唯一索引,那么竞争事务之一会因异常而失败(当试图创建 X 的副本时)。
我如何实现 #find_or_create_by
的“安全版本”,它永远不会引发任何异常并始终按预期工作?
最佳答案
答案在 doc 中
Whether that is a problem or not depends on the logic of the application, but in the particular case in which rows have a UNIQUE constraint an exception may be raised, just retry:
begin
CreditAccount.find_or_create_by(user_id: user.id)
rescue ActiveRecord::RecordNotUnique
retry
end
解决方案一
如果您需要保持 DRY,您可以在您的模型或关注中实现以下内容
def self.find_or_create_by(*)
super
rescue ActiveRecord::RecordNotUnique
retry
end
用法:Model.find_or_create_by(X)
方案二
或者如果您不想覆盖find_or_create_by
,您可以将以下内容添加到您的模型中
def self.safe_find_or_create_by(*args, &block)
find_or_create_by *args, &block
rescue ActiveRecord::RecordNotUnique
retry
end
用法:Model.safe_find_or_create_by(X)
关于ruby-on-rails - 如何仅在记录不存在时才创建记录,避免重复并且不引发任何错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14331926/
我是一名优秀的程序员,十分优秀!