PaperTrail手动创建版本

时间:2015-01-06 18:00:31

标签: ruby-on-rails import version spreadsheet paper-trail-gem

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

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

导入CSV时,我当前使用" past_version"标记第二行。但我现在认为实现一个完整的版本化gem将是一个更好的方法。

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

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

这可能吗?

3 个答案:

答案 0 :(得分:3)

@Flori的touch_with_version方法有效,但是当他们使touch为可记录事件时,paper_trail弃用了此方法。

在最新版本的paper_trail上,您可以执行以下操作:

model.paper_trail.save_with_version

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

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

无法自定义事件...您可以创建,还原,更新和触摸,但至少在没有大量猴子补丁或其他操作的情况下,不能做为“手动”记录之类的事情。< / p>

即使这样做,也有些背叛,因为您调用的某些内部组件可能会在将来的版本中更改。它还具有一些必需的参数,这些参数已随着版本的不同而变化。

就我而言,我正在一起使用paper_trail和妄想症,并希望在还原时记录一个明确的版本,除非您执行上述操作,否则似乎绕过paper_trail。

答案 1 :(得分:1)

万一有人偶然发现了这个问题:这是可能的!您可以在任何PaperTrail模型上调用touch_with_version,如下所示:mymodel.paper_trail.touch_with_version。它会为你创建一个版本。

答案 2 :(得分:0)

对于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