Callback executed like after_save but after transaction

I’m trying to add some code for my ActiveRecord class so that it is
executed whenever an object is updated, this code is a seperate
process that reads from the same table represented by my model class
so when it runs it needs the database to be up to date.

In the following situation this is fine:

MyModel

def after_save
/usr/local/bin/update_models -i #{self.id}
end

controller action delete

def delete
MyModel.find(params[:id]).update_attribute(:deleted_at, Time.now) #
after_save is called when the table
end

But in this situation:

controller action new

def new
MyModel.transaction do
newmodel = MyModel.new
othermodel = MyOtherModel.new
… other code …
newmodel.save!
othermodel.save!
end
end

after_save gets called inside the transaction, and so the database is
not up to date! I’ve looked into ActiveRecord::Observers but this also
faces the same problem. Is there any way around this?

Here is my idea for how this might be achieved, given no knowledge

of how to accomplish it the rails way

comments / feedback / criticism welcomed

(note this is just a proof of concept not rails compatible code)

class ActiveRecord

def self.transaction(&block)
Thread.current[‘after_commit_procs’] ||= []
block.call

Thread.current['after_commit_procs'].each do |proc|
  proc.call
end

end

def save
if self.respond_to?(:after_commit) then
Thread.current[‘after_commit_procs’] <<
self.method(:after_commit)
end
puts “Saving…”
end

end

class MyRecord < ActiveRecord

def after_commit
puts “after_commit callback called!”
end
end

MyRecord.transaction do
rec = MyRecord.new
puts “Before save”
rec.save
puts “After save, before commit”
end
puts “After commit”

output:

Before save

Saving…

After save, before commit

after_commit callback called!

After commit

Thinking Sphinx defines an after_commit callback to run the indexer
for delta indexes. It is based on this post:

Eli Miller: Proper cache expiry with after_commit

You can check the actual code in lib/thinking_sphinx/active_record/
delta.rb.