纸上谈兵的宝石能力[英] Paper_trail gem abilities

本文是小编为大家收集整理的关于纸上谈兵的宝石能力的处理方法,想解了纸上谈兵的宝石能力的问题怎么解决?纸上谈兵的宝石能力问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我想知道是否可以使用 papertrail gem 实现以下用例?一种维基百科类型的应用程序,其 wiki 页面登录用户可以更改/编辑,其中:

  1. 版主可以撤消特定更改:
    我知道 papertrail 允许回滚到以前的版本,但我在这里问的有点不同.也就是说,能够撤消特定的编辑/更改.假设一个记录/wiki 页面有三个编辑/版本.然后,如果您想撤消编辑 2,则编辑 1 和 3 的更改仍应保留.但是如果你回滚到编辑 2 之前的版本,那么编辑 3 也会被撤消,这不是我想要的.

  2. 用户所做的更改(贡献)反馈到用户的个人资料中,然后将概述该用户所做的更改/贡献:
    我相信使用 --with-changes 选项(除了已更改资源的完整转储之外还注册所做的更改)以及 papertrail 注册已进行更改的用户这一事实,这是可能的.我的理解正确吗?
    在教程 http://samurails.com/gems/papertrail/ 我读到了关于结合使用 papertrail使用 gem diffy 来确定确切更改的内容,但我不明白为什么教程使用 diffy 而 papertrail 本身已经提供了"差异"功能?

  3. 在实际实施更改之前(即实际应用更改之前)让版主首先接受某些用户的更改:
    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 或任何类似的库.

版主接受更改

我认为在单个字段中实现并不容易.您可能需要为"已接受"和"原始"数据设置两列,甚至可能需要两个不同的模型.

我想我涵盖了你所有的问题,这对你很有帮助.

本文地址:https://www.itbaoku.cn/post/786771.html