I have after_commit setup as folllows.
class MyModel < ActiveRecord::Base
after_commit { Rails.logger.info ("commit here") }
# ...
end
I am then wrapping update_all, which doesn't fire a callback, inside a transaction, which is supposed to fire a callback.
MyModel.transaction do
MyModel.update_all(col: 'awesome')
end
Why isn't the after_commit being fired? I don't see "commit here" in my logs. It works for destroy just fine.
The way after_commit
works is that whenever a record is saved it gets added to a list of records. When the transaction gets committed, rails iterates over that list calling the after commit hooks on each one.
When you do update_all
the instances aren't saved individually (since they aren't actually loaded at all - rails doesn't actually know which rows were updated) and so they don't get added to the list that power after_commit
.
destroy_all
is different because it does actually load all the instances and delete them one by one, firing all callbacks. You'd observe similar behaviour to update_all
if you used delete_all
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With