You can't declare after_*_commit or after_commit callbacks for the same method more than once!
wow.
In Rails ActiveRecord, I just discovered that if you do this:
# bad code!
after_update_commit :thing
after_create_commit :thing
Only the second one will take effect! After asking in the rails slack, I was pointed to the docs which actually cover this:
Using both after_create_commit and after_update_commit with the same method name will only allow the last callback defined to take effect, as they both internally alias to after_commit which overrides previously defined callbacks with the same method name.
To me, the docs are ambiguous about if "which overrides" refers to the aliasing or to the behavior of after_commit
. Sadly, it's the latter. This has the same problem:
# bad code!
after_commit :thing, on: :update
after_commit :thing, on: :create
In my examples above, the problem can be easily solved with
after_commit :thing, on: [:update, :create]
But it's trickier if you have conditions
# bad code!
after_commit :thing, on: :update, if: :is_active?
after_commit :thing, on: :create
One way to work around this is with this not so elegant but perfectly acceptable code, using *_previously_changed?
:
after_commit :thing, on: [:update, :create]
def thing
# id_previously_changed? is only true when record is created
unless id_previously_changed?
return unless is_active?
end
# ...
end