0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

update_all で更新かけられると after_commit がフックしない

Posted at

という事象に出くわしてちょっとハマったので、メモをとりあえず残しておく。

起こった時のバージョンは 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と同様の挙動を見ることができます。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?