Paper_trail gem abilities

a 夏天 提交于 2020-01-02 06:21:59

问题


I was wondering whether the following use case can be achieved using the papertrail gem? A Wikipedia-type of application with wiki pages that logged in users can change/edit and where:

  1. Moderators can undo specific changes:
    I understand papertrail allows to roll back to a previous version but what I’m asking here is somewhat different. That is, the ability to undo a specific edit/change. Suppose there have been three edits/versions to a record/wiki-page. Then if you want to undo edit 2, then changes from edit 1 and 3 should still remain. But if you would roll back to the version before edit 2, then also edit 3 would be undone, which is not what I want here.

  2. Changes made (contributions) by a user feed back into the user’s profile, which would then have an overview of the changes/contributions made by that user:
    I believe this is possible using the --with-changes option (which registers the change that was made in addition to the full dump of the changed resource) in combination with the fact that papertrail registers the user who has made a change. Am I correct in my understanding?
    In the tutorial http://samurails.com/gems/papertrail/ I read about using papertrail in combination with the gem diffy to establish what was changed exactly, but what I don’t understand is why the tutorial uses diffy when papertrail itself already offers a “diffing” functionality?

  3. To have moderators first accept a change by some users, before that change is actually implemented (i.e., before the change is actually applied):
    Can papertrail also help to achieve this functionality?


回答1:


1. Moderators can undo specific changes

You can achieve this functionality using the following module:

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

It adds revert_to method to the model which allows moderator to undo only changes in specific edit. Pay attention to SKIP_FIELDS array, which excludes several system fields, which should not be reverted.

We can easily test this module. Let's create a table:

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

  t.timestamps null: false
end

and associated model:

class Article < ActiveRecord::Base
  include Revertible
  has_paper_trail
end

The following test case shows, that only version specific edits were reverted:

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.Changes made (contributions) by a user

To turn on changes tracking add the following method to your application controller:

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

Changes made by a specific user can be easily tracked now:

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

Diffy

As to your question about diffy. You don't actually need it if the only thing you need is to get difference between two adjacent versions. But if you need to compare changes between version separated by several edits, then you do need diffy or any similar library.

Moderator accepts changes

I don't think it's easy to implement in a single field. You probably need to have two columns for "accepted" and "raw" data, maybe even two different models.

I think I covered all you questions and it was helpful for you.



来源:https://stackoverflow.com/questions/32348047/paper-trail-gem-abilities

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!