ActiveRecordのAfter〇〇ではまったこと

やりたかったこと

hogehoge.update!

after_save do
  // 外部サービスをAPIアクセス
end

みたいな特定のテーブル更新時に、別サービスを呼び出すみたいなことをやってみたかった。

何が問題だったか

テーブル更新したはずなのに、外部サービスで SELECT しても更新前のデータしか取得できなかった...

原因

BEGIN

before_save
update ...
after_save

COMMIT

という流れでafter_save段階では、まだcommitされてない状態になっていた...

commit の後には、after_commit を使うべきらしい。

結局、model内で他のサービス呼ぶのは積極的には使いたくないなと思って、hookで行うのは辞めたが、はまったのでメモ。

ちゃんとドキュメントには書いてある

Active Record コールバック - Railsガイド

その他

before_save とかは、changed? で今まで行けたけど、after_save では、saved_change_to_attribute? としないと変更を取れなかった

多重トランザクション

この前、Railsの多重トランザクション調べた時に知った、update! はトランザクションを生成するってことを覚えておけば、すぐ気づけた...

【翻訳】ActiveRecordにおける、ネストしたトランザクションの落とし穴 - Qiita