概要
- 主にActiveRecordと併用して使うステータス管理用のgemがあります。
- AASM(ステートマシーン)です。
- 「ステータス変更と同時に別の処理を実行したい」という要求を満たすために排他制御(主にデータベースのトランザクション)を使う場面がありますが、どのコールバックを使うのかがAASMのドキュメント内で明示されていなかったので書いておきます。
問題
- よくAASMのサンプルコードで見つけるのが、
after_commit
コールバックに処理をしたいメソッドを書く方法です。
AASM - classの状態遷移をスマートに実装するためのgem (Ruby, Active Record, Sequel, Mongoid) - Qiita
AASM - Ruby state machinesここを参考にしました。…
- 上記にあるコードでは、ステータスの変更が終わったら通知をするというような別に処理を行っても問題ない処理なのでコードは正しいです。
- 要するに、after_commitはその名の通りAASMによって管理されているステータスが更新されたことをDBにコミットした後に実行されます。
- しかしながら、AASMで管理するステータスと別のテーブルにあるステータスを同時に更新する場合に
after_commit
コールバックを使うだけでは不十分です。
アプローチ
after
コールバックを使います。
afterコールバックを使うと、AASMで管理するステートと同じトランザクション内で実行されます。
aasm/lib/aasm/aasm.rb at master · aasm/aasm
AASM - State machines for Ruby classes (plain Ruby, ActiveRecord, Mongoid, NoBrainer, Dynamoid) - aasm/aasm
afterコールバックは、event
とtransitionに対して設定できます。
余談
requires_lock: true
は付ける必要があります。
Comments