8

我有一个项目电子表格,我将其转换为 CSV 并使用自定义导入脚本导入到基于 Rails 的应用程序中。

电子表格包含每条记录的一行,但有些行包含先前行的不同版本。

导入 CSV 时,我目前使用“past_version”字段标记第二行,但我现在认为实现完整版本控制 gem 将是一种更好的方法。

我一直在阅读 PaperTrail 的文档,它看起来非常适合我所追求的,但是,我需要创建一些行的版本作为我的导入脚本的一部分。这可以用 PaperTrail 完成吗?

基本上我需要开始导入,比如正常添加记录 1、2、3、4、5,然后记录 6 实际上是记录 2 的更新版本,所以我现在需要手动创建 PaperTrail 版本。

这可能吗?

4

3 回答 3

8

@Flori 的 touch_with_version 方法有效,但 paper_trail 在制作touch可记录事件时弃用了此方法。

在最新版本的 paper_trail 上,您可以这样做:

model.paper_trail.save_with_version

如果您使用的是旧版本,而这不可用,则可以使用该record_update方法(这是save_with_version内部使用的方法):

model.paper_trail.record_update(force: true, in_after_callback: false)

没有办法自定义事件......你可以创建、恢复、更新和触摸,但不能做一些事情,比如将它记录为“手动”,至少在没有大量猴子补丁或其他东西的情况下是这样。

即使这样做也有点危险,因为您调用的一些内部结构可能会在未来版本中发生变化。它还具有一些必需的参数,这些参数已从版本更改为版本。

就我而言,我同时使用 paper_trail 和 paranoia,并希望在还原时记录一个显式版本,这似乎绕过了 paper_trail,除非您执行上述操作。

于 2019-01-12T16:46:03.120 回答
1

对于 PaperTrail 4.0.0 和 Rails 4.2.0

我必须手动创建自己的版本,以便我可以使用该update_column方法(否则不会触发 PaperTrail。

#instance method in model to generate new version and create object_changes

  def generate_version!(object_attrs, changed_attrs)
     object_changes_attrs = {}
     changed_attrs.each do |k, v|
       object_changes_attrs[k] = v
     end
     object_value = self.class.paper_trail_version_class.object_col_is_json? ? object_attrs : PaperTrail.serializer.dump(object_attrs)
     object_changes_value = self.class.paper_trail_version_class.object_col_is_json? ? object_changes_attrs : PaperTrail.serializer.dump(object_changes_attrs)
     data = {
       event: 'update', # or any custom name you want
       whodunnit: PaperTrail.whodunnit,
       object: object_value,
       object_changes: object_changes_value
     }
     send(self.class.versions_association_name).create! merge_metadata(data)
   end

然后在你的模型中,你可以在任何你想传入的地方调用它:(1)当前对象属性的哈希(更新之前);(2) 属性的哈希值和所做的更改

#some method where you do not otherwise trigger PaperTrail

def my_method
  old_updated_at = self.updated_at
  new_updated_at = DateTime.now.utc
  object_attrs = self.attributes
  self.update_columns(prioritized: true, updated_at: new_updated_at)
  self.generate_version!(object_attrs, { 'prioritized': [false, true], 'updated_at': [old_updated_at, new_updated_at] })
end
于 2017-11-03T16:10:39.917 回答
1

万一有人偶然发现这个问题:有可能!您可以像这样调用touch_with_version任何 PaperTrail 模型mymodel.paper_trail.touch_with_version:它将为您创建一个版本。

于 2016-11-15T09:06:37.587 回答