メモ
gormのUpdateColumnsはUpdatedAtを更新しない。
その仕組みを実際のコードとともに整理してみた。
その他のUpdateメソッドの挙動はついでに以下に整理した。
https://qiita.com/yukiyoshimura/items/a6fa5ac9ff1bd8d03be5
背景
gormの UpdateColumns
を使っていたところUpdatedAtが更新されてないことに気づいた。
以下にHookメソッドをスキップするときに使ってねみたいなのが書いてある。Hookメソッド内でUpdatedAtを更新しているのだろうか・・・ちょっとはっきりしたものは見つけられないが、フックをスキップしているところを追ってみる。
https://gorm.io/docs/update.html#Without-Hooks-x2F-Time-Tracking
実際にコードをみてみる
UpdateColumnsの処理をみる。
tx.Statement.SkipHooks = true
でskipセットしている。
https://github.com/go-gorm/gorm/blob/master/finisher_api.go#L421
func (db *DB) UpdateColumns(values interface{}) (tx *DB) {
tx = db.getInstance()
tx.Statement.Dest = values
tx.Statement.SkipHooks = true
return tx.callbacks.Update().Execute(tx)
}
UpdateColumnsから呼ばれる。Updateの処理を見る。
https://github.com/go-gorm/gorm/blob/master/callbacks/update.go#L56
// Update update hook
func Update(config *Config) func(db *gorm.DB) {
supportReturning := utils.Contains(config.UpdateClauses, "RETURNING")
//
//
// ここの処理は今回は特に気にする必要はない。Hookはこの関数の実行後に呼ばれる
最後にhookで呼ばれる処理を見る
https://github.com/go-gorm/gorm/blob/master/callbacks/update.go#L108
!db.Statement.SkipHooks
あった!これでスキップされることを確認できた。
// AfterUpdate after update hooks
func AfterUpdate(db *gorm.DB) {
if db.Error == nil && db.Statement.Schema != nil && !db.Statement.SkipHooks && (db.Statement.Schema.AfterSave || db.Statement.Schema.AfterUpdate) {
callMethod(db, func(value interface{}, tx *gorm.DB) (called bool) {
以上