1

我有一个哈希数组(大约 20k),我需要导入但需要验证,并且还必须使用 paper_trail 创建版本。

arr = [{some_1_id: '1', some_2_id: '2', some_3_id: '3', amount: '123'}, {some_1_id: '1', some_2_id: '2', some_3_id: '3', amount: '123'}]

我有一个这样的哈希数组。在此,我们可以预期大约 20k 元素需要保存到 DB。

我使用了 activerecord-import,但它绕过了所有回调,包括 paper_trail 回调。

我试图像这样运行回调

books.each do |book|
  book.run_callbacks(:save) { false }
  book.run_callbacks(:create) { false }
end
Book.import(books)

但它没有正确保存 paper_trail 版本。

我所做的是

arr.each do |a|
 valid_books = []
 book_obj = Book.new
 # validate some_1_id
 # validate some_2_id   
 # validate some_3_id
 # Some other validations
 if book_obj.valid?
   valid_books << book_obj
 end
end
 # Run call backs 
 Book.import valid_books

它按预期工作,但性能一点也不好。10k 条记录需要 30 多秒。

提前致谢。

4

1 回答 1

0

10k 条记录需要 30 多秒。

30s 在正常验证和创建 10k 版本化记录的预期性能范围内(即,,,带有newPT回调)。在某些应用程序中,30 秒会被认为很快,尤其是在验证和其他回调执行它们自己的查询时。valid?save

我建议将导入过程放在后台作业中,并简单地要求用户等待。

如果导入已经在后台作业中,或者 bg. 工作是不可能的,你可以探索使用activerecord-import两次:首先创建 30kBook记录,然后创建 30kPaperTrail::Version记录。这是一种高级技术,使用 PT 的私有(不受支持)API。要正确实例化PaperTrail::Version对象,PaperTrail::Events::Create请使用PaperTrail::RecordTrail#build_version_on_create。如果你成功地使用了这种技术,我很乐意查看一个 PR,将它添加到我们的 README 中。

于 2021-02-01T20:39:41.873 回答