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!
after_touch
is a good idea, but might be tricky to prevent duplicate versions ofRecord
. Instead, what about starting a transaction, updating yourData
, updating yourRecord
, then committing the transaction. If all the updates happen in the same transaction, what result do you get? – HouseboundData
belong_to
theRecord
, so all those saves just happen in the course of create/update forRecord
. One other wrinkle--if multipleData
would create multiple versions onRecord
, I think I need to keep the last version, not the first, if I want Record to be synced with its Data. Thanks for your advice--I'm still new to Rails and I'm not sure if I'm quite thinking in Rails yet. Working on it! – UpwindRecord
's data attributes are already in a transaction(I think?) because of the Rails association. Should I turn off the paper_trail callbacks, like:has_paper_trail on: []
, and then create my ownafter_create
andafter_update
callbacks with ``` Record.transaction do record.update record.touch_with_version end ``` – Upwindbelongs_to :record, touch: true
in my Datum class, it would create the timestamp I want on my Record. – Upwind