From 40b51709ff396efe40d2cd884c88e2b60cd5f03e Mon Sep 17 00:00:00 2001 From: Paolo Galeone Date: Sun, 22 Nov 2015 21:48:32 +0100 Subject: [PATCH] Use the sql default value (of the tag field) when updating a field to a blank value --- callback_update.go | 12 +++++++++--- structs_test.go | 1 + update_test.go | 18 ++++++++++++++++-- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/callback_update.go b/callback_update.go index b710f40e..e45a3a84 100644 --- a/callback_update.go +++ b/callback_update.go @@ -51,10 +51,16 @@ func Update(scope *Scope) { fields := scope.Fields() for _, field := range fields { if scope.changeableField(field) && !field.IsPrimaryKey && field.IsNormal { - if !field.HasDefaultValue || !field.IsBlank { - sqls = append(sqls, fmt.Sprintf("%v = %v", scope.Quote(field.DBName), scope.AddToVars(field.Field.Interface()))) - } else if field.HasDefaultValue { + if field.HasDefaultValue { + if field.IsBlank { + defaultValue := strings.Trim(parseTagSetting(field.Tag.Get("sql"))["DEFAULT"], "'") + sqls = append(sqls, fmt.Sprintf("%v = %v", scope.Quote(field.DBName), scope.AddToVars(defaultValue))) + } else { + sqls = append(sqls, fmt.Sprintf("%v = %v", scope.Quote(field.DBName), scope.AddToVars(field.Field.Interface()))) + } scope.InstanceSet("gorm:force_reload", true) + } else { + sqls = append(sqls, fmt.Sprintf("%v = %v", scope.Quote(field.DBName), scope.AddToVars(field.Field.Interface()))) } } else if relationship := field.Relationship; relationship != nil && relationship.Kind == "belongs_to" { for _, dbName := range relationship.ForeignDBNames { diff --git a/structs_test.go b/structs_test.go index 9a9b23d1..b52e64ef 100644 --- a/structs_test.go +++ b/structs_test.go @@ -134,6 +134,7 @@ type Animal struct { unexported string // unexported value CreatedAt time.Time UpdatedAt time.Time + Cool bool `sql:"default:false"` } type JoinTable struct { diff --git a/update_test.go b/update_test.go index 71aa7c43..244e0dec 100644 --- a/update_test.go +++ b/update_test.go @@ -87,10 +87,11 @@ func TestUpdateWithNoStdPrimaryKeyAndDefaultValues(t *testing.T) { DB.Save(&animal) updatedAt1 := animal.UpdatedAt + // Sleep for a second and than update a field + time.Sleep(1000 * time.Millisecond) DB.Save(&animal).Update("name", "Francis") - if updatedAt1.Format(time.RFC3339Nano) == animal.UpdatedAt.Format(time.RFC3339Nano) { - t.Errorf("updatedAt should not be updated if nothing changed") + t.Errorf("updatedAt should be updated when changing a field") } var animals []Animal @@ -118,6 +119,19 @@ func TestUpdateWithNoStdPrimaryKeyAndDefaultValues(t *testing.T) { if animal.Name == "" { t.Errorf("Update a filed with an associated default value should not occur when trying to insert an empty field. The default one should be inserted\n") } + + // Animal.Cool has a default value thats equal to the Zero of its type. (false) I have to update this field to true and false without problems + animal.Cool = true + DB.Save(&animal) + if !animal.Cool { + t.Errorf("I should update a field with a default value to someother value") + } + + animal.Cool = false + DB.Save(&animal) + if animal.Cool { + t.Errorf("I should update a field with an associated blank value to its blank value") + } } func TestUpdates(t *testing.T) {