众所周知Model.find_or_create_by(X)实际上可以做到:

  • 由X
  • 选择
  • (如果未找到)->由X创建
  • 返回记录(已找到或已创建)

  • 并且在步骤1和步骤2之间可能存在竞争条件。为避免数据库中X重复,应在X的字段集上使用唯一索引。但是,如果应用唯一索引,则竞争事务中的一个将失败。异常(尝试创建X的副本时)。

    我该如何实现#find_or_create_by的“安全版本”,该版本永远不会引发任何异常并且始终可以按预期运行?

    最佳答案

    答案在doc



    解决方案1 ​​

    您可以在模型中实现以下功能,或者在需要保持干燥状态的情况下实现关注

    def self.find_or_create_by(*)
      super
    rescue ActiveRecord::RecordNotUnique
      retry
    end
    

    用法:Model.find_or_create_by(X)
    解决方案2

    或者,如果您不想覆盖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/

    10-17 01:50