Renra
Renra

Reputation: 5649

Rails does not fire my after_commit callback

Hello I have a peculiar problem. I use an after_commit callback to send notifications, but it seems the callback is not triggered at all. Simplified the situation looks like this:

class Message < ActiveRecord::Base
  after_commit :do_something

  def do_something
    raise 'Doing something'
  end
end

Then I expected to see the raise when I open the console and create a message. But nothing happens. Furthermore rails does not even complain if I delete the 'do_something' method completely. Note that this is not a test with transactional fixtures. I even see the record committed in the db. My rails version is 3.0.9. Thanks for any help especially if it's good :-)

Edit: I learned later that the callback DID get triggered when I deployed the code to a different machine. So it must be something with my setup. Still I would appreciate your insight about what could be causing this.

Edit2: From the comments.

Upvotes: 11

Views: 16709

Answers (6)

lulalala
lulalala

Reputation: 17981

One possible cause (at least on 5.0) is:

after_commit :do_something, on: :create
after_commit :do_something, on: :destroy

here do_something is referenced twice, and none will be executed. Once it is combined to

after_commit :do_something, on: [:create, :destroy]

it would be called again.

Upvotes: 7

reto
reto

Reputation: 16732

David mentioned the explanation for this behavior in the questions comment.

Transaction Callbacks documentation

"If any exceptions are raised within one of these callbacks, they will be ignored so that they don't interfere with the other callbacks. As such, if your callback code could raise an exception, you'll need to rescue it and handle it appropriately within the callback."

see also:

Upvotes: 7

felipeclopes
felipeclopes

Reputation: 4070

You have the following:

class Message < ActiveRecord::Base
  after_commit :do_something

  def do_something
    puts 'Doing something'
  end
end

You may try with after_create or after_save depending on your needs.

after_commits just execute when the record is sucessfully saved in database, because save, save! and destroy runs within transactions.

As found in documentation: Active Record Callbacks

Upvotes: -2

Chris Aitchison
Chris Aitchison

Reputation: 4654

You may need to put a patch in your spec/support to enable after_commit callbacks when using transactional fixtures. If you are using transaction fixtures then a commit doesn't actually ever happen.

The patch: https://gist.github.com/charleseff/1305285

Upvotes: 3

Narmadha
Narmadha

Reputation: 55

Try if below code helps -

class Message < ActiveRecord::Base
 after_commit :do_something, :only => [:create, :update, :destroy]

 def do_something
  raise 'Doing something'
 end
end

Upvotes: 0

Aditya Kapoor
Aditya Kapoor

Reputation: 1570

You should specify the action when this after_commit must be triggered....

The after_commit is basically used in those Databases where the concept of transaction is present...So try the following code...

class Message < ActiveRecord::Base
 after_commit :do_something, :on => [:create, :update, :destroy]

 def do_something
  raise 'Doing something'
 end
end

Upvotes: 0

Related Questions