'after_commit and after_destroy callbacks are not called on ActiveRecord::Relation delete_by method
I am using ActiveRecord::Relation delete_by method to delete a record but this is not triggering after_commit and after_destroy callbacks. See below example:
class User < ActiveRecord::Base
after_commit :expire_cache
after_destroy :expire_cache
def expire_cache
puts "expire_cache is called"
end
end
User.delete_by(user_id: 1234) # doesn't trigger expire_cache method
Is my expectation about the callbacks is right? What am I doing wrong?
Solution 1:[1]
Is my expectation about the callbacks is right?
No. Your expectation to trigger a callback with delete_by is wrong.
What am I doing wrong?
Your understanding is not matching with doc.
As per the Doc, skipping-callbacks
delete_all will skip the callbacks
delete_allJust as with validations, it is also possible to skip callbacks.
- These methods should be used with caution, however, because important business rules and application logic may be kept in callbacks. Bypassing them without understanding the potential implications may lead to invalid data.
Solution 2:[2]
If you want your callbacks to run, use destroy_by instead:
User.destroy_by(id: 1234)
These methods were introduced in Rails 6. More info here:
- https://blog.saeloun.com/2019/10/15/rails-6-delete-by-destroy-by.html
- https://github.com/rails/rails/issues/35304
Knowing the differences between delete and destroy also helps:
Difference between Destroy and Delete
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Sergio Gonzalez |
