我想知道使用papertrail gem是否可以实现以下用例?
具有已登录用户的Wiki页面的Wikipedia类型的应用程序可以更改/编辑,并且在以下位置:


主持人可以撤消特定更改:
我了解papertrail可以回滚到以前的版本,但是我在这里要问的是有些不同。也就是说,撤消特定编辑/更改的能力。假设对记录/ Wiki页面进行了三个编辑/版本。然后,如果要撤消编辑2,则仍应保留对编辑1和3所做的更改。但是,如果您要回滚到编辑2之前的版本,那么编辑3也将被撤消,这不是我想要的。
用户所做的更改(贡献)会反馈到用户的个人资料中,然后该个人资料将概述该用户所做的更改/贡献:

我相信使用--with-changes选项(除了注册已更改资源的全部转储之外还注册已进行的更改)并结合papertrail注册已进行更改的用户这一事实,是可行的。我的理解正确吗?

在教程http://samurails.com/gems/papertrail/中,我读到了关于将papertrail与gem diffy结合使用以建立确切更改的内容,但是我不明白的是,为什么当papertrail本身已经提供了“差异”时,教程使用diffy功能?
要让主持人先接受某些用户的更改,然后再实际实施更改(即,在实际应用更改之前):

Papertrail还可以帮助实现此功能吗?

最佳答案

1.版主可以撤消特定更改

您可以使用以下模块来实现此功能:

module Revertible
   SKIP_FIELDS = [ 'updated_at' ]

   def revert_to(version)
     raise 'not version of this model' unless self == version.item
     changes = version.changeset.select{ |k, v| not SKIP_FIELDS.include?(k) }.map{ |k,v| [k.to_sym, v[0]] }.to_h
     self.update_attributes(changes)
  end
end


它将revert_to方法添加到模型中,该方法允许主持人仅撤消特定编辑中的更改。请注意SKIP_FIELDS数组,该数组排除了几个系统字段,不应将其还原。

我们可以轻松地测试该模块。让我们创建一个表:

create_table :articles do |t|
  t.string :title
  t.string :body

  t.timestamps null: false
end


和相关模型:

class Article < ActiveRecord::Base
  include Revertible
  has_paper_trail
end


以下测试案例显示,仅还原了特定于版本的编辑:

class ArticleTest < ActiveSupport::TestCase
  test "rollback specific edit" do
    article = Article.create(title: 'My Article 1', body: 'first version')
    article.update_attributes(title: 'My Article 1', body: 'second version')
    article.update_attributes(title: 'My Article 3', body: 'third version')

    assert_equal 3, article.versions.count
    assert_equal 'My Article 3', article.title
    assert_equal 'third version', article.body

    article.revert_to article.versions[1]

    assert_equal 4, article.versions.count
    assert_equal 'My Article 3', article.title # title haven't changed
    assert_equal 'first version', article.body # body did change
  end
end


2.用户所做的更改(贡献)

要打开更改跟踪,请在您的应用程序控制器中添加以下方法:

class ApplicationController
  def user_for_paper_trail
    user = current_user
    return 'public' if user.blank?
    user.username
  end
end


现在可以轻松跟踪特定用户所做的更改:

versions = PaperTrail::Version.where(whodunnit: 'dimakura')
version = versions.first
version.item # => #<Article id: 1, title: "...", body: "...">
version.event # => "create"
version.changeset


迪菲

关于您关于diffy的问题。如果您唯一需要做的就是获得两个相邻版本之间的差异,那么您实际上并不需要它。但是,如果需要比较由多个编辑分隔的版本之间的更改,则确实需要diffy或任何类似的库。

主持人接受更改

我认为在单个领域中实施起来并不容易。您可能需要有两列用于“接受”和“原始”数据,甚至可能有两个不同的模型。

我想我涵盖了您所有的问题,对您有所帮助。

10-05 18:17