ペーパートレイルのようなレールでのオブジェクトバージョン化
-
27-10-2019 - |
質問
現在取り組んでいるプロジェクトでは、オブジェクトバージョンを実装する必要があります。残念ながら、各オブジェクトの完全な履歴を保持する必要があるため、PaperTrailのような単一のテーブルソリューションはすぐに管理できなくなります。ただし、私が好きなペーパートレイルの特徴がありますが、各モデルの個々のテーブルを使用したソリューションで見つけることができませんでした(Acts_As_versionedなど)。
- コントローラーとモデルの両方からメタ情報を保存する機能
- データはシリアル化されるため、スキーマの変更はバージョンテーブルを変更しません
- トラバースバージョンのための強力な方法
- 変更責任の自動追跡
また、ペーパートレイルにはボーナスではないいくつかの機能があります。
- 組み込みバージョンDIFFサポート
- フルバージョンの代わりに微分
現在、各モデルに個々のテーブルを使用するためにPaperTrailのフォーキングを検討していますが、既存のソリューションがある場合はその努力を節約したいと考えています。
アップデート:Vestalバージョンはデフォルトで単一のテーブルを使用しますが、各モデルにカスタムバージョンクラスを提供し、ActivereCordの「set_table_name」メソッドを使用することにより、各モデルに個別のテーブルを作成することができました。 VestalバージョンにもDIFFサポートが組み込まれていますが、そのインターフェイスはPapertrailsほど強力ではありません。また、関連性のサポートもありません。
更新2:Papertrailはよりアクティブなプロジェクトのように思われるので、私は宝石を分岐し、モデルごとに個別のテーブルを定義できるVestalバージョンと同様のカスタムクラスサポートに追加されました。私のフォークはここにありますが、まもなくメインプロジェクトリポジトリに引き込まれることを願っています。https://github.com/benzittlau/paper_trail
解決
class_nameオプションを使用して、カスタムバージョンのサブクラスを指定できます。
class Post < ActiveRecord::Base
has_paper_trail :class_name => 'PostVersion'
end
class PostVersion < Version
# custom behaviour, e.g:
self.table_name = :post_versions # in rails 2, use set_table_name
end
これにより、各モデルのバージョンを別のテーブルに保存できます。これは、多くのバージョンが作成されている場合に役立ちます。
他のヒント
私は使用しています Vestalバージョン, 、Mementoパターンを使用して履歴テーブルを作成するRails Gem/プラグインを使用して、After_SaveおよびAfted_destroyコールバックで属性の違いを保存します。
また、変更されたときに記録し、バージョン番号を増やして、特定のバージョンまたは特定の日付または時刻に存在するバージョンにロールバックできます。
その後、次のようなオブジェクトを引き上げることができます:
@user = User.last
@user.versions.last.changes #=> {:name => ['Robert','Bob']}
私はかなり大ファンです。