0
0

GORM UpdateColumnsはUpdatedAtを更新しない

Last updated at Posted at 2024-07-23

メモ

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

finisher_api.go
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.go
// 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 あった!これでスキップされることを確認できた。

update.go
// 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) {

以上

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