ruby-on-rails-4 - find_or_create_by 使用 mongoid 和 sidekiq 会导致重复

标签 ruby-on-rails-4 mongoid sidekiq

Rails 4.0.2、Mongoid git alpha、sidekiq 2.17.0

使用工作人员解析 CSV 文件并将内容放入 mongo,但遇到了几个问题...最明显的是使用 find_or_create_by 时,同名的产品最终会成为重复文档。

class Category
  include Mongoid::Document
  field :title, type: String

  has_many :products
end

Class Product
  include Mongoid::Document
  field :name, type: String

  belongs_to: :category
end

Class ProductWorker
  include Sidekiq::Worker

  def perform(category, name)
    category = Category.find_or_create_by( title: category )
    product = Product.find_or_create_by(name: name)
    product.category = category
    product.save
  end
end

对于同一类别中只有两种产品的 CSV 文件,我最终会得到两个具有相同名称的类别条目,每个产品都位于不同的类别中。当我删除 sidekiq 异步并直接在模型上执行它时,我得到了 1 个类别和两个关系产品的正确结果。

如果工作人员执行 find_and_create_by 的速度足够快,那么两个工作人员都会找到 nil 并因此创建新对象,这是有道理的。我怎样才能防止这种情况发生?

最佳答案

唯一性验证是不够的,因为它们是由 Mongoid 在模型级别定义的。

保证唯一性的唯一方法是定义 unique indexes :

class Category
  include Mongoid::Document
  field :title, type: String

  has_many :products

  index({ title: 1 }, background: true, unique: true)

  validates_uniqueness_of :title
end

关于ruby-on-rails-4 - find_or_create_by 使用 mongoid 和 sidekiq 会导致重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20873913/

相关文章:

ruby-on-rails - acts_as_taggable_on tag_cloud 抛出未定义的方法 `empty?' 为 nil :NilClass

ruby-on-rails - 具有多个对象和整数键的 Rails 4 强参数

ruby-on-rails-4 - Rails4 弃用警告

find - mongoid 找到 VS 在哪里

ruby-on-rails - 使用 ActionController::Live 流式传输在生产环境中不起作用

ruby-on-rails - Sidekiq 列出所有作业 [已排队 + 正在运行]

ruby-on-rails - Mongoid 5.0 - Rails 4 - 收集表格 has_many

ruby-on-rails - Mongoid/Mongodb 和查询嵌入文档

ruby-on-rails - 在 Rails 中运行 native mongodb 命令

ruby-on-rails - Rails、Sidekiq - Redis NOAUTH