LoginSignup
3
3

More than 5 years have passed since last update.

【Rails】一括updateでコールバックを呼べるのか検証してみた

Last updated at Posted at 2019-01-31

はじめに

複数のモデルを一括でupdate、かつ、コールバックを呼ぶ方法がないのかなと思い、いろいろ探してみました。

で、結論から言うと、コールバックを走らせずに一括updateするのは無理っぽいです><

クラスメソッドとして使えるのは以下の二つですが、まず前提としてどれもコールバックが走りませんでした。
update_all
update_columns

参考:
https://qiita.com/tyamagu2/items/8abd93bb7ab0424cf084

updateを使えばできる?

updateを使えばいけるっぽいという情報を聞いたので実践してみました。
今回はidが1と2のユーザーのageを20に一括updateするのが目的。
これをupdate_allと同じ要領でできるかと思ったら?


@users.updaete([1,2], age: 20)
ArgumentError: When assigning attributes, you must pass a hash as an argument

え。。
どうやらもしidと属性の数が合わなかったらrollbackされるようです。

正しくはこうです


@users.update([1,2], [{ age: 20 }, { age: 20 }])

これは非常に面倒臭い。。
しかもidの数だけ属性を書かないといけません。
なぜこのような仕様にしたのでしょうか。。
参考: http://o.inchiki.jp/obbr/198

ならばバルクアップデートはどうだろう

と思い、こんな感じに早速やってみた。


users = []
@users.each do |user|
  user.age = 20
  users << user
end

User.import users, on_duplicate_key_update: [:age]

が、updateはされてもコールバックは呼ばれず。。

結論

一個づつupdateしよう;;


@users.each { |user| user.update(age: 20) }

はい、結局これに落ち着きました。。

もし他にやり方があるよ!っていう神様がいましたら教えていただけると飛んで喜びます(m_ _m)

3
3
2

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
3
3