という事象に出くわしてちょっとハマったので、メモをとりあえず残しておく。
起こった時のバージョンは Rails 5.1.6
調べてないけど現在は解消されているのだろうか? (そもそもの挙動を考えると多分そのままな気がする)
ほぼ下記の事例と同じ状況で、回答者の内容を deeplしたのがこちら。
https://stackoverflow.com/questions/10921919/after-commit-not-getting-called-after-update-all
原文:
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
訳文:
after_commitの動作は、レコードが保存されるたびにレコードのリストに追加されます。トランザクションがコミットされると、railsはそのリストを繰り返し処理し、それぞれのレコードに対してafter commitフックを呼び出します。
update_allを実行した場合、インスタンスは個別に保存されず(実際には全くロードされていないので - railsはどの行が更新されたかを実際には知りません)、after_commitを実行するリストに追加されません。
destroy_allが違うのは、実際に全てのインスタンスをロードして、全てのコールバックを発生させて一つずつ削除するからです。delete_allを使用した場合、update_allと同様の挙動を見ることができます。