Paper_trail драгоценные способности

Мне было интересно, можно ли достичь следующего варианта использования с помощью драгоценного камня papertrail? Приложение типа Wikipedia с вики-страницами, в которые заходят пользователи, может изменяться / редактироваться и где:

  1. Модераторы могут отменить определенные изменения:
    Я понимаю, что papertrail позволяет откатиться к предыдущей версии, но то, что я здесь спрашиваю, несколько иное. То есть возможность отмены конкретного редактирования / изменения. Предположим, было три редактирования / версии записи / вики-страницы. Затем, если вы хотите отменить редактирование 2, изменения от редактирования 1 и 3 все равно должны остаться. Но если вы вернетесь к версии до редактирования 2, то также будет отменено редактирование 3, чего я здесь не хочу.

  2. Изменения, сделанные (вклады) пользователем, возвращаются обратно в профиль пользователя, в котором затем будет представлен обзор изменений / вкладов, внесенных этим пользователем:
    Я считаю, что это возможно с помощью --with-changes опция (которая регистрирует изменение, внесенное в дополнение к полному дампу измененного ресурса) в сочетании с тем, что papertrail регистрирует пользователя, который внес изменение. Правильно ли я понимаю?
    В учебнике http://samurails.com/gems/papertrail/ я читал об использовании papertrail в сочетании с драгоценным камнем diffy чтобы установить, что именно изменилось, но я не понимаю, почему в учебнике используется diffy когда сам по себе papertrail предлагает "отличную" функциональность?

  3. Чтобы модераторы сначала приняли изменение некоторыми пользователями, до того, как это изменение будет фактически реализовано (т. Е. До того, как изменение будет фактически применено):
    Может ли papertrail также помочь в достижении этой функциональности?

1 ответ

Решение

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, На самом деле вам это не нужно, если вам нужно только получить разницу между двумя смежными версиями. Но если вам нужно сравнить изменения между версиями, разделенными несколькими изменениями, то вам нужно diffy или любая подобная библиотека.

Модератор принимает изменения

Я не думаю, что это легко реализовать в одной области. Вам, вероятно, нужно иметь два столбца для "принятых" и "необработанных" данных, возможно, даже две разные модели.

Я думаю, что я охватил все ваши вопросы, и это было полезно для вас.

Другие вопросы по тегам