Techioz Blog

紙の証跡の object_changes をオーバーライドして、ID の変更に対応する名前を保存する

概要

関連付けの場合、別のモデルの ID を自分のモデルに割り当てているため、ID が変更されます。 Papertrail はそれらの変更を追跡します。これが私の object_changes の状態です。

{
  "updated_at": [
    "2023-11-13T08:54:26.346Z",
    "2023-11-13T08:56:06.961Z"
  ],
  "paying_id": [
    "ID1",
    "ID1 new"
  ],
  "company_ids": [
    [
      "ID1",
      "ID2",
      "ID3",
      "ID4"
    ],
    [
      "ID1 new",
      "ID2 new",
      "ID3 new"
    ]
  ]
}

ただし、監査ログの観点では、ID を表示するのではなく、それらの ID に対応する名前を表示したいと考えています。現在、if ループを使用して名前をクエリし、ビューに送信しています。しかし、これよりも良い方法があるはずです。ドキュメントでは object_changes のオーバーライドにも反対していますが、object_changes がオーバーライドされない場合はどうすればよいでしょうか?

これを行う正しい方法は何ですか?

解決策

ログはそのままにして、ID のみをログに保存します。また、会社のレコードをソフト削除可能にします。つまり、会社が破棄された場合、実際にはデータベースから削除されるのではなく、デフォルトのワークフローで Rails に対して「非表示」になります。独自の論理的な削除ロジックを実装することも、宝石の 1 つ (つまり paranoia) を使用することもできます。

想像してみてください。既存の会社の社名が変更されたらどうなるでしょうか?会社名を文字列として別の場所に複製すると、データの不整合が生じます。

本当にログを保存したい場合は、company_ids フィールドが変更された場合にのみ、meta を使用して会社名を保存できます。何かのようなもの

has_paper_trail(
    meta: {
      company_names: proc { |item| item.company_ids.changed? ? list_of_company names : nil }
    }
  )

しかし、_changed? がわかりません。それとも_以前_変更されましたか?この範囲内で利用可能です。これにより、企業の数に応じて巨大な文字列も生成されます。別の方法としては、list_of_added_company_names と list_of_removed_company_names の 2 つのキーを持つハッシュを保存する方法があります。これは多少優れていますが、それでもデータの重複が発生します。