# Callback executed like after\_save but after transaction

**URL:** <https://www.ruby-forum.com/t/callback-executed-like-after-save-but-after-transaction/144301>\
**Category:** Rails\
**Created:** [July 28, 2008, 1:29pm UTC](https://www.ruby-forum.com/t/callback-executed-like-after-save-but-after-transaction/144301 "2008-07-28T13:29:00Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jbjbjb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/82dd89/32.png) [@jbjbjb](https://www.ruby-forum.com/u/jbjbjb)\
**Post date:** [July 28, 2008, 1:29pm UTC](https://www.ruby-forum.com/t/callback-executed-like-after-save-but-after-transaction/144301/1 "2008-07-28T13:29:00Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![jbjbjb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/82dd89/32.png) [@jbjbjb](https://www.ruby-forum.com/u/jbjbjb)\
**Post date:** [July 31, 2008, 5:30am UTC](https://www.ruby-forum.com/t/callback-executed-like-after-save-but-after-transaction/144301/2 "2008-07-31T05:30:26Z")

</div>

# 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

---

<div class="post-metadata">

**Author:** ![jbjbjb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/82dd89/32.png) [@jbjbjb](https://www.ruby-forum.com/u/jbjbjb)\
**Post date:** [August 13, 2008, 7:09pm UTC](https://www.ruby-forum.com/t/callback-executed-like-after-save-but-after-transaction/144301/3 "2008-08-13T19:09:30Z")

</div>

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](http://elimiller.blogspot.com/2007/06/proper-cache-expiry-with-aftercommit.html)

You can check the actual code in lib/thinking\_sphinx/active\_record/  
delta.rb.
