【问题标题】:PaperTrail Manually create versionPaperTrail 手动创建版本
【发布时间】:2015-01-06 18:00:31
【问题描述】:

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

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

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

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

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

这可能吗?

【问题讨论】:

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


    【解决方案1】:

    @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)
    

    没有办法自定义事件...您可以创建、恢复、更新和触摸,但不能执行诸如将其记录为“手动”之类的操作,至少在没有大量猴子修补或其他东西的情况下是这样。

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

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

    【讨论】:

    • 这似乎没有检测到自上次记录以来更改的实际属性,因此它有点没用。
    【解决方案2】:

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

    【讨论】:

    • 如果您在版本控制中忽略了 updated_at 则不起作用
    【解决方案3】:

    适用于 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-25
      相关资源
      最近更新 更多