Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Paper Trail: create a version on parent whenever associated model changes?

I'm working on a Rails app where I need to show the audit trail on a Record, which has_many Data. I have paper_trail on my Record, and associated Datum models, and it is saving versions of them just fine.

However, what I need is for one version for Record to be created whenever one or more associated Data are changed. Currently, it creates versions on each Datum that changes, but it only creates a version of the Record if the Record's attributes change; it's not doing it when the associated Data change.

I tried putting touch_with_version in Record's after_touch callback, like so:

class Record < ActiveRecord::Base
  has_many :data

  has_paper_trail

  after_touch do |record|
    puts 'touched record'
    record.touch_with_version
  end

end

and

class Datum < ActiveRecord::Base
  belongs_to :record, :touch => true

  has_paper_trail

end

The after_touch callback fires, but unfortunately it creates a new version for each Datum, so when a Record is created it already has like 10 versions, one for each Datum.

Is there a way to tell in the callbacks if a version has been created, so I don't create multiples? Like check in one of the Record callbacks and if Datum has already triggered a version, don't do any more?

Thanks!

like image 868
David Ham Avatar asked Oct 20 '22 00:10

David Ham


1 Answers

This works for me.

class Place < ActiveRecord::Base
  has_paper_trail
  before_update :check_update

  def check_update
    return if changed_notably?

    tracking_has_many_associations = [ ... ]
    tracking_has_has_one_associations = [ ... ]

    tracking_has_many_associations.each do |a|
      send(a).each do |r|
        if r.send(:changed_notably?) || r.marked_for_destruction?
          self.touch
          return
        end
      end
    end
    tracking_has_one_associations.each do |a|
      r = send(a)
      if r.send(:changed_notably?) || r.marked_for_destruction?
        self.touch
        return
      end
    end
  end
end
like image 185
Tom Avatar answered Nov 03 '22 02:11

Tom