Rails / Papertrail: Changeset with association changes
Asked Answered
A

2

8

I am stuck. I've been trying to figure out how to include the association changes (has_many, has_many through) on a model that has papertrail. I would like to call MyModel.versions.first.changeset and have any changes that took place on associated objects be included in the .changeset hash that is returned from that version of the object.

I've added the migrations for version associations:

class CreateVersionAssociations < ActiveRecord::Migration
  def self.up
    create_table :version_associations do |t|
      t.integer  :version_id
      t.string   :foreign_key_name, :null => false
      t.integer  :foreign_key_id
    end
    add_index :version_associations, [:version_id]
    add_index :version_associations, [:foreign_key_name, :foreign_key_id], :name => 'index_version_associations_on_foreign_key'
  end

  def self.down
    remove_index :version_associations, [:version_id]
    remove_index :version_associations, :name => 'index_version_associations_on_foreign_key'
    drop_table :version_associations
  end
end


class AddTransactionIdColumnToVersions < ActiveRecord::Migration
  def self.up
    add_column :versions, :transaction_id, :integer
    add_index :versions, [:transaction_id]
  end

  def self.down
    remove_index :versions, [:transaction_id]
    remove_column :versions, :transaction_id
  end
end

I have added Papertrail to the associated objects, but as far as I can tell, there is no documentation discussing retrieving changes that took place on the associated objects. Can anyone assist on if this is possible using Papertrail?

I am trying to implement an audit trail of changes on a model and its associated objects that can be accessed in one changeset.

Applesauce answered 11/8, 2015 at 22:34 Comment(2)
I think I'm looking for a similar feature. I would like to record a belongs_to change on the has_many object. Like, if a Person has many PhoneNumbers and you change/add/delete a persons number, it'll record that change as a change to the person not record it as a change to the phone number.Hertfordshire
@Hertfordshire yeah i gave it a try a while back, but it doesnt look like these types of assocaition tracking have made it fully into papertrail yet, heres an oldish ticket describing some difficulties, they have been working on it for future version, i keep an eye on it every once in a while github.com/airblade/paper_trail/issues/503Applesauce
B
4

The information you need is ultimately stored in the relevant tables versions and version_associations.

However, paper_trail does not provide the methods for you to access the information in the way you want. But you can write a custom method yourself to get a list of the associations's versions of an object.

Let's say you have the following models:

class Article < ApplicationRecord
    has_many :comments
    has_paper_trail
end

class Comment < ApplicationRecord
    belongs_to :article
    has_paper_trail
end

You can find all the comment versions of an article object article this way:

PaperTrail::Version.where(item_type: 'Comment')
                   .joins(:version_associations)
                   .where(version_associations: { foreign_key_name: 'article_id', foreign_key_id: article.id })
                   .order('versions.created_at desc')

You can monkey patch the gem, or define this method as an instance method on the Article class so you can call it easily, eg article.comment_versions

Note, the above information isn't available in the article.versions.first.changeset, because if you change a comment but not the article, the article is not versioned, only the comment is.

But the method above allows you to access the history of changes to the associations.

Bellyache answered 12/9, 2017 at 11:40 Comment(1)
I could be wrong here, but I believe if you change belongs_to :article to belongs_to :article, touch: true, then you will be able to trigger a new version on the parent object even if the only thing that's changed is the child object.Janus
V
-1

Looks like this has been added as an experimental feature to the papertrail gem

check out the docs here https://github.com/airblade/paper_trail/blob/v4.2.0/README.md#associations

This change will require the addition of a new database table for papertrail to keep track of associated models.

Vanish answered 10/3, 2017 at 18:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.