Paper_trail драгоценные способности
Мне было интересно, можно ли достичь следующего варианта использования с помощью драгоценного камня papertrail? Приложение типа Wikipedia с вики-страницами, в которые заходят пользователи, может изменяться / редактироваться и где:
Модераторы могут отменить определенные изменения:
Я понимаю, что papertrail позволяет откатиться к предыдущей версии, но то, что я здесь спрашиваю, несколько иное. То есть возможность отмены конкретного редактирования / изменения. Предположим, было три редактирования / версии записи / вики-страницы. Затем, если вы хотите отменить редактирование 2, изменения от редактирования 1 и 3 все равно должны остаться. Но если вы вернетесь к версии до редактирования 2, то также будет отменено редактирование 3, чего я здесь не хочу.Изменения, сделанные (вклады) пользователем, возвращаются обратно в профиль пользователя, в котором затем будет представлен обзор изменений / вкладов, внесенных этим пользователем:
Я считаю, что это возможно с помощью--with-changes
опция (которая регистрирует изменение, внесенное в дополнение к полному дампу измененного ресурса) в сочетании с тем, что papertrail регистрирует пользователя, который внес изменение. Правильно ли я понимаю?
В учебнике http://samurails.com/gems/papertrail/ я читал об использовании papertrail в сочетании с драгоценным камнемdiffy
чтобы установить, что именно изменилось, но я не понимаю, почему в учебнике используетсяdiffy
когда сам по себе papertrail предлагает "отличную" функциональность?Чтобы модераторы сначала приняли изменение некоторыми пользователями, до того, как это изменение будет фактически реализовано (т. Е. До того, как изменение будет фактически применено):
Может ли 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
или любая подобная библиотека.
Модератор принимает изменения
Я не думаю, что это легко реализовать в одной области. Вам, вероятно, нужно иметь два столбца для "принятых" и "необработанных" данных, возможно, даже две разные модели.
Я думаю, что я охватил все ваши вопросы, и это было полезно для вас.