Rails 模型版本控制 - 一种具有独立版本列的模型

发布于 2024-11-17 04:29:45 字数 502 浏览 4 评论 0原文

我有一个具有 wiki 功能的多语言网站模型,其中包含我希望进行版本控制的各个字段,但是我需要恢复对某些列而不是其他列所做的更改。

例如,我为每个模型实例存储了英语和西班牙语版本的书面指南。

想象一下:

  • 用户 A 编辑了西班牙语指南并添加了脏话
  • 用户 B 随后编辑了英语指南并进行了有用的更改。

通常版本控制意味着恢复用户 A 所做的更改也将恢复用户 B 稍后的更改,尽管在我的例子中这是两个不同的问题。

所以我本质上需要有范围版本历史记录。例如使用 papertrail:

#guide.rb
has_paper_trail :only => [:en_title, :en_body]
has_paper_trail :only => [:es_title, :es_body]

有什么最简单的解决方案吗?我真的不想只是为了实现这一目标而将我的指南转移到具有一对一关系的单独模型中。

I have a model for a multilingual website with wiki functionality which contains various fields I wish to have versioned, however I need to revert changes made to some columns but not others.

For example, I store the English and Spanish versions of a written guide for each model instance.

Imagine:

  • User A edits the Spanish guide and adds profanity
  • User B later edits the English guide and makes useful changes.

Typically versioning means that reverting the changes made by user A also will revert later changes by User B, despite the fact that in my case these are two separate concerns.

So I need to essentially have scoped version histories. For example using papertrail:

#guide.rb
has_paper_trail :only => [:en_title, :en_body]
has_paper_trail :only => [:es_title, :es_body]

Any easiest solution for this? I really don't want to move my guides into separate models with a one to one relationship just to achieve this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷弦 2024-11-24 04:29:45

尽管我个人会将翻译提取到他们自己的模型中以避免这种情况,但您仍然应该能够在没有太多技巧的情况下实现这一目标。

每次更改记录时,PaperTrail 都会创建一个新的 Version 对象。每个版本都可以通过 object.versions 数组访问。

您必须想出一种方法来决定要恢复哪个属性以及要将其恢复到哪个版本。一旦你有了这个,恢复它应该不会很困难。

例如,在您的模型中:

# Arguments:
#   attr - Must respond to to_s with name of attribute to revert
#   ver  - Integer (e.g. -1 for previous version) or actual Version object
def revert_attribute(attr, ver)
  ver = self.versions[ver] if ver.class == Integer
  ver = ver.reify
  self.write_attribute( attr, ver.read_attribute(attr) )
  self.save
end

代码未经过测试或语法检查,但应该可以根据我在 PaperTrail 源代码中看到的内容进行工作。

它不是一个完美的集成解决方案,但应该足以满足大多数需求。

Although I'd personally extract translations into their own model to avoid this, you should still be able to achieve this without too much trickery.

PaperTrail creates a new Version object every time a record is changed. Every version is accessible through the object.versions array.

You'll have to come up with a way to decide which attribute you want to revert and which version you want to revert it back to. Once you have this, reverting it shouldn't be very difficult.

For example, in your model:

# Arguments:
#   attr - Must respond to to_s with name of attribute to revert
#   ver  - Integer (e.g. -1 for previous version) or actual Version object
def revert_attribute(attr, ver)
  ver = self.versions[ver] if ver.class == Integer
  ver = ver.reify
  self.write_attribute( attr, ver.read_attribute(attr) )
  self.save
end

Code isn't tested or syntax checked, but ought to work from what I've seen in the PaperTrail source.

It's not a perfectly integrated solution, but it should be adequate for most needs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文