Reputation: 1164
after_save
is called when the record is saved (but before it's committed). While after_create
is called, well, after database transaction has been committed.
Other than this post http://www.justinweiss.com/articles/a-couple-callback-gotchas-and-a-rails-5-fix/ which explain Sidekiq job can't find an object because the code is running before the object is committed, what are other gotchas that I need to know in order to decide wheter after_create
or after_commit
is more suitable to be used?
Upvotes: 3
Views: 2978
Reputation: 3454
If you're trying to avoid Sidekiq being 'too fast', as you're describing, the solution that I most commonly see is to use after_commit
.
This has one large disadvantage - If you're updating something in the model, the after_commit
hook will run again. Make sure this will never happen.
See the example:
You're creating a TextMessage
and saving this to the database with status='unsent'
, and in an after_commit
hook, you're adding a SidekiqJob for sending this to your SMS Gateway, via an API.
This API returns an ID, for tracking it remotely, and you then update this to your TextMessage from earlier. This will trigger a resend of the TextMessage.
Of course, after_commit
also responds to on: :update
and on: create
, like before_save
etc does.
Here, you could, in the job, ensure that the job is unsent
before, but this may still trigger a resend, even though you've ensured this.
It's easy to make infinite loops in this, and it may cost you quite a lot if you're not careful.
Upvotes: 7