Techioz Blog

PaperTrail でのバージョン変更を、その後のバージョン変更を上書きせずに元に戻すことはできますか?

概要

Paper_trail gem を使用してバージョン管理されたモデルを含む Rails プロジェクトがあります。

バージョンを復元するときに、その特定のバージョンで変更されたフィールドのみを元に戻し、その後のバージョンのさまざまなフィールドの変更を元に戻さないようにしたいと考えています。

たとえば、名前、お気に入りの色、年齢のフィールドを持つ人物モデルがあるとします。

# Let's say this doesn't create any version
Person.create(name: 'John', age: 20, favorite_color: 'Green') 

# This creates a version (V1) with the changeset: 20 => 21
Person.update_attributes(age: 21)

# This creates another version (V2) with the changeset: 'Green' => 'Blue'                
Person.update_attributes(favorite_color: 'Blue')

# This creates another version (V3) with the changeset: 'John' => 'James'
# This is also the latest version now
Person.update_attributes(name: 'James')

私が探している機能は、V1 に戻して人の年齢を 20 歳に戻す場合、その後の変更 (つまり、お気に入りの色の変更と名前の変更) を元に戻したくないことです。したがって、特定のフィールドの変更を元に戻したいだけであると言った方が適切だと思います。 (この場合、年齢: 20 歳、お気に入りの色: 「ブルー」、名前: 「ジェームズ」の人です)。

これはPaperTrailがすでにサポートしているものだと思います。これらの方針に沿った内容のドキュメントとコードをスキャンし、Google で検索し、過去の問題を調べましたが、何も見つかりませんでした。

そこで私の本当の質問は、私がそれを見逃したのか、それとも単に PaperTrail がサポートしていないものなのかということです。

これが PaperTrail で実際にサポートされているかどうかがわかるまで、revert と呼ばれる関数を使用してこれをサポートするように PaperTrail::Version を拡張しました。

興味がある場合は、次のコードを参照してください。

# app/models/paper_trail/version.rb

module PaperTrail
  class Version < ActiveRecord::Base
    include PaperTrail::VersionConcern

    def revert
      item = self.item
      item_attributes = {}

      self.changeset.keys.each do |k|
        item_attributes[k] = self.changeset[k][0]
      end

      item.assign_attributes(item_attributes)
      item
    end
  end
end

解決策

私がやったとき:

some_record.paper_trail.previous_version.save

これにより、望ましい状態の新しいバージョンが作成されました。中間のバージョンは上書き/置換されませんでした。