Skip to content

Commit d34bcec

Browse files
committed
fix
1 parent baaff00 commit d34bcec

File tree

1 file changed

+30
-17
lines changed

1 file changed

+30
-17
lines changed

callbacks/update.go

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,24 +32,37 @@ func SetupUpdateReflectValue(db *gorm.DB) {
3232
// BeforeUpdate before update hooks
3333
func BeforeUpdate(db *gorm.DB) {
3434
if db.Error == nil && db.Statement.Schema != nil && !db.Statement.SkipHooks && (db.Statement.Schema.BeforeSave || db.Statement.Schema.BeforeUpdate) {
35-
callMethod(db, func(value interface{}, tx *gorm.DB) (called bool) {
36-
// save a copy before executing the hook so that can find out which fields were modified after the hook is executed.
37-
rv := reflect.Indirect(reflect.ValueOf(value))
38-
rvClone := reflect.New(rv.Type()).Elem()
39-
rvClone.Set(rv)
40-
35+
callMethod(db, func(value interface{}, tx *gorm.DB) bool {
36+
var (
37+
beforeSaveInterface BeforeSaveInterface
38+
isBeforeSaveHook bool
39+
beforeUpdateInterface BeforeUpdateInterface
40+
isBeforeUpdateHook bool
41+
)
4142
if db.Statement.Schema.BeforeSave {
42-
if i, ok := value.(BeforeSaveInterface); ok {
43-
called = true
44-
db.AddError(i.BeforeSave(tx))
45-
}
43+
beforeSaveInterface, isBeforeSaveHook = value.(BeforeSaveInterface)
4644
}
47-
4845
if db.Statement.Schema.BeforeUpdate {
49-
if i, ok := value.(BeforeUpdateInterface); ok {
50-
called = true
51-
db.AddError(i.BeforeUpdate(tx))
52-
}
46+
beforeUpdateInterface, isBeforeUpdateHook = value.(BeforeUpdateInterface)
47+
}
48+
49+
var (
50+
called bool
51+
rv reflect.Value
52+
rvSnapshot reflect.Value
53+
)
54+
if isBeforeSaveHook || isBeforeUpdateHook {
55+
called = true
56+
// save a snapshot of the struct before the hook was called
57+
rv = reflect.Indirect(reflect.ValueOf(value))
58+
rvSnapshot = reflect.New(rv.Type()).Elem()
59+
rvSnapshot.Set(rv)
60+
}
61+
if isBeforeSaveHook {
62+
db.AddError(beforeSaveInterface.BeforeSave(tx))
63+
}
64+
if isBeforeUpdateHook {
65+
db.AddError(beforeUpdateInterface.BeforeUpdate(tx))
5366
}
5467

5568
if called {
@@ -61,8 +74,8 @@ func BeforeUpdate(db *gorm.DB) {
6174
if !ok {
6275
continue
6376
}
64-
// compare with the copy value and update the field if there is a difference
65-
if !reflect.DeepEqual(rv.FieldByName(field.Name).Interface(), rvClone.FieldByName(field.Name).Interface()) {
77+
// compare with the snapshot and update the field if there is a difference
78+
if !reflect.DeepEqual(rv.FieldByName(field.Name).Interface(), rvSnapshot.FieldByName(field.Name).Interface()) {
6679
db.Statement.SetColumn(dbFieldName, rv.FieldByName(field.Name).Interface())
6780
}
6881
}

0 commit comments

Comments
 (0)