【问题标题】:Object versioning in Rails, like Papertrail but individual tablesRails 中的对象版本控制,如 Papertrail,但单独的表
【发布时间】:2011-03-17 23:05:47
【问题描述】:

对于我目前正在进行的项目,我需要实现对象版本控制。不幸的是,我需要保留每个对象的完整历史记录,因此像 Papertrail 这样的单表解决方案很快就会变得无法管理。不过,Papertrail 有一些我喜欢的功能,但我无法在每个模型都有单独的表的解决方案中找到这些功能(例如acts_as_versioned)。

  • 能够存储来自控制器和模型的元信息
  • 数据已序列化,因此架构更改不会修改版本表
  • 遍历版本的强大方法
  • 自动跟踪变更责任

还有一些 Papertrail 不具备的功能可以作为奖励:

  • 内置版本差异支持
  • 差异版而非完整版

我目前正在考虑分叉 Papertrail 以便为每个模型使用单独的表,但如果有现有的解决方案,我希望节省这项工作。

更新: Vestal 版本默认使用单个表,但通过为每个模型提供自定义版本类并使用 ActiveRecord 的“set_table_name”方法,我能够为每个模型创建单独的表。 Vestal Versions 还内置了差异支持,尽管它的界面不如 Papertrails 强大。它也缺乏关联支持。

更新 2: 由于 papertrail 似乎是一个更活跃的项目,我已经分叉了 gem 并添加了类似于 Vestal 版本的自定义类支持,现在允许为每个模型定义单独的表。我的 fork 在这里,但我希望它很快会被拉入主项目存储库。 https://github.com/benzittlau/paper_trail

【问题讨论】:

  • 为什么每个模型都需要一个单独的表?老式插件acts_as_versioned 就是这样工作的。
  • 每个模型都需要一个单独的表,因为所有版本化对象的单个表会迅速增长到无法管理的大小,特别是因为我希望经常读取和写入此表。跨度>

标签: ruby-on-rails versioning database-versioning


【解决方案1】:

您可以使用 :class_name 选项指定自定义版本子类:

class Post < ActiveRecord::Base
  has_paper_trail :class_name => 'PostVersion'
end

class PostVersion < Version
  # custom behaviour, e.g:
  self.table_name = :post_versions # in rails 2, use set_table_name
end

这允许您将每个模型的版本存储在单独的表中,如果您要创建大量版本,这将非常有用。

【讨论】:

  • 我们真的需要使用 set_table_name,因为它是类的默认派生表名吗? PostVersion => post_versions
  • 确实是你的类继承自AR::Base,这里不是这样。
  • 在一个表中已经有一堆历史记录后,我可以开始使用不同的表吗?
  • 当然可以,只要迁移你关心的所有数据
【解决方案2】:

我一直在使用Vestal Versions,这是一个使用 memento 模式创建历史表的 rails gem/plugin,它在 after_save 和 after_destroy 回调中保存了不同的属性。

它还会记录更改时间并增加版本号,以便您可以回滚到某个版本或某个日期或时间存在的版本。

然后我可以像这样拉出一个对象:

@user = User.last
@user.versions.last.changes #=> {:name => ['Robert','Bob']}

我是个超级粉丝。

【讨论】:

  • Vestal 版本,如 Papertrail,使用单个表来存储其版本化对象,因此不适合我的应用程序,如原始帖子中所述。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-22
  • 2021-02-18
相关资源
最近更新 更多