Версии объектов в Rails, например Papertrail, но отдельные таблицы

Для проекта, над которым я сейчас работаю, мне нужно реализовать управление версиями объектов. К сожалению, мне нужно сохранить полную историю каждого объекта, поэтому одно табличное решение, такое как Papertrail, быстро станет неуправляемым. Однако есть особенности Papertrail, которые мне нравятся, которые я не смог найти в решении с отдельными таблицами для каждой модели (например, act_as_versioned).

  • Возможность хранения метаинформации как с контроллера, так и с модели
  • Данные сериализуются, поэтому изменения схемы не изменяют таблицу версий.
  • Мощные методы для перемещения версий
  • Автоматическое отслеживание ответственности за изменение.

Есть также некоторые функции, которые Papertrail не имеет, которые будут бонусами:

  • Поддержка встроенной версии diff
  • Дифференциал вместо полных версий

В настоящее время я рассматриваю forking Papertrail для использования отдельных таблиц для каждой модели, но хотел бы сохранить это усилие, если есть существующее решение.

Update: Версии Vestal по умолчанию используют одну таблицу, но, предоставляя собственный класс версии для каждой модели и используя метод set_table_name ActiveRecord, я смог создать отдельные таблицы для каждой модели. Vestal Versions также имеет встроенную поддержку diff, хотя ее интерфейс не такой мощный, как Papertrails. Он также не имеет поддержки ассоциации.

Обновление 2: Поскольку papertrail, кажется, более активный проект, я разветкил драгоценный камень и добавил в поддержку пользовательского класса, аналогичную версии vestal, которая теперь позволяет определять отдельные таблицы для каждой модели. Моя вилка здесь, но я надеюсь, что она будет втянута в главный репозиторий проекта в ближайшее время. https://github.com/benzittlau/paper_trail

Ответ 1

Вы можете указать пользовательские подклассы версии с параметром: class_name:

class Post < ActiveRecord::Base
  has_paper_trail :class_name => 'PostVersion'
end

class PostVersion < Version
  # custom behaviour, e.g:
  set_table_name :post_versions
end

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

Ответ 2

Я использовал Vestal Versions, gem/plugin rails, который использует шаблон памяти, чтобы создать таблицу истории, и это экономит diff атрибутов в after_save и after_destroy обратных вызовах.

Он также записывает, когда он был изменен и увеличивает номер версии, чтобы вы могли откат к определенной версии или версии, присутствующей в определенную дату или время.

Затем я могу вытащить такой объект:

@user = User.last
@user.versions.last.changes #=> {:name => ['Robert','Bob']}

Я довольно большой поклонник.