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
,那么两个工人都会找到零并因此创建新对象。我该如何防止这种情况?
答案 0 :(得分:0)
看起来缺少uniqueness validation。
class Category
include Mongoid::Document
field :title, type: String
has_many :products
validates_uniqueness_of :title # Won't duplicate records
end
您还可以使用其他more accurate querying:
Category.where(title: category).first_or_create!
这样,如果出现其他问题,您甚至可以rescue
。
答案 1 :(得分:0)
唯一性验证是不够的,因为它们是由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