如何使用纸迹获取模型的原始属性

How to get original attribute for a model with paper trail

我有一个用纸迹跟踪的模型。我需要将当前值与创建的值模型进行比较。到目前为止,我可以轻松获得当前值。我如何获得原件?

获取当前值:widget.name

获取原文:widget.versions.first.???.name

我知道 widget.versions.first.changeset 会 return 像这样的散列:

{
  name: [nil, 'original name']
}

但我不想解析出来,必须有更好的方法

我不是要这样做:

original = widget.versions.where(event: 'create')[0].changeset['name'][1]

丑陋但效果很好。猴子能把它修补成 paper_trail 来清理它吗

在第二个 version 上使用 reify 或 return 如果 widget 不存在。

在 Github 仓库中有一个关于 reify returning nilclosed issue。它在那里被忽略了,但我认为这是一个非常有效的问题并且很常见 use-case。

widget.versions.first.reify returns nil 所以我能找到的最好方法是:

widget.versions.second.reify

但是当对象没有任何变化时,这不起作用。所以你需要 nil 在那里签到:

widget.versions.second&.reify || widget

这将查找第二个版本,如果存在,将调用 reify,return 是原始对象。如果它不存在,它只会 return widget 本身。

如果你想把它弄清楚,你可以把这个作为方法添加到 class:

# Returns the original version of this object or just this object if there has been no changes.
def original_version
  self.versions.second&.reify || self
end

我有一个开放的 Issue/Feature 请求与 PaperTrail 将 original_version 添加到核心库本身:

https://github.com/paper-trail-gem/paper_trail/issues/1204

如果你想要它,请给它一个赞。

您还可以做的事情(有点老套,不能适用于所有用例)是:

class MyModel
  has_paper_trail on: [:touch]
  after_save { touch }
end

这样:

  • 您的版本中有创建版本
  • 你的版本中有live版本
  • 但是您不能再利用版本#event(它将始终是“touch”)