From 0f00493c505145aedd451115d2d0f8c9dcbe5980 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Tue, 15 Dec 2020 11:18:29 +0800 Subject: [PATCH] Continue to update tracking fields even not selected with Select, but skip them if omited with Omit, fix #3856 --- callbacks/create.go | 2 +- callbacks/update.go | 26 ++++++++++++-------------- tests/update_test.go | 4 +++- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/callbacks/create.go b/callbacks/create.go index 3ca56d73..052f3344 100644 --- a/callbacks/create.go +++ b/callbacks/create.go @@ -244,7 +244,7 @@ func ConvertToCreateValues(stmt *gorm.Statement) (values clause.Values) { for _, db := range stmt.Schema.DBNames { if field := stmt.Schema.FieldsByDBName[db]; !field.HasDefaultValue || field.DefaultValueInterface != nil { - if v, ok := selectColumns[db]; (ok && v) || (!ok && !restricted) { + if v, ok := selectColumns[db]; (ok && v) || (!ok && (!restricted || field.AutoCreateTime > 0 || field.AutoUpdateTime > 0)) { values.Columns = append(values.Columns, clause.Column{Name: db}) } } diff --git a/callbacks/update.go b/callbacks/update.go index c8f3922e..db5b52fb 100644 --- a/callbacks/update.go +++ b/callbacks/update.go @@ -202,7 +202,7 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) { for _, dbName := range stmt.Schema.DBNames { field := stmt.Schema.LookUpField(dbName) if field.AutoUpdateTime > 0 && value[field.Name] == nil && value[field.DBName] == nil { - if v, ok := selectColumns[field.DBName]; (ok && v) || (!ok && !restricted) { + if v, ok := selectColumns[field.DBName]; (ok && v) || !ok { now := stmt.DB.NowFunc() assignValue(field, now) @@ -226,21 +226,19 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) { for _, dbName := range stmt.Schema.DBNames { field := stmt.Schema.LookUpField(dbName) if !field.PrimaryKey || (!updatingValue.CanAddr() || stmt.Dest != stmt.Model) { - if v, ok := selectColumns[field.DBName]; (ok && v) || (!ok && !restricted) { + if v, ok := selectColumns[field.DBName]; (ok && v) || (!ok && (!restricted || (!stmt.SkipHooks && field.AutoUpdateTime > 0))) { value, isZero := field.ValueOf(updatingValue) - if !stmt.SkipHooks { - if field.AutoUpdateTime > 0 { - if field.AutoUpdateTime == schema.UnixNanosecond { - value = stmt.DB.NowFunc().UnixNano() - } else if field.AutoUpdateTime == schema.UnixMillisecond { - value = stmt.DB.NowFunc().UnixNano() / 1e6 - } else if field.GORMDataType == schema.Time { - value = stmt.DB.NowFunc() - } else { - value = stmt.DB.NowFunc().Unix() - } - isZero = false + if !stmt.SkipHooks && field.AutoUpdateTime > 0 { + if field.AutoUpdateTime == schema.UnixNanosecond { + value = stmt.DB.NowFunc().UnixNano() + } else if field.AutoUpdateTime == schema.UnixMillisecond { + value = stmt.DB.NowFunc().UnixNano() / 1e6 + } else if field.GORMDataType == schema.Time { + value = stmt.DB.NowFunc() + } else { + value = stmt.DB.NowFunc().Unix() } + isZero = false } if ok || !isZero { diff --git a/tests/update_test.go b/tests/update_test.go index a660647c..df709cff 100644 --- a/tests/update_test.go +++ b/tests/update_test.go @@ -466,7 +466,9 @@ func TestSelectWithUpdateColumn(t *testing.T) { var result2 User DB.First(&result2, user.ID) - AssertEqual(t, lastUpdatedAt, result2.UpdatedAt) + if lastUpdatedAt.Format(time.RFC3339Nano) == result2.UpdatedAt.Format(time.RFC3339Nano) { + t.Errorf("UpdatedAt should be changed") + } if result2.Name == user.Name || result2.Age != user.Age { t.Errorf("Should only update users with name column")