From 474edd63a77fab21c98a1e12884ed9eb2fc80726 Mon Sep 17 00:00:00 2001 From: Jacques Racagneres Date: Thu, 26 Sep 2019 01:42:26 +0100 Subject: [PATCH] Fix Blank Associated Values --- callback_update.go | 2 +- callbacks_test.go | 4 ++-- migration_test.go | 2 +- update_test.go | 54 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/callback_update.go b/callback_update.go index 699e534b..0cad8c2d 100644 --- a/callback_update.go +++ b/callback_update.go @@ -76,7 +76,7 @@ func updateCallback(scope *Scope) { for _, field := range scope.Fields() { if scope.changeableField(field) { if !field.IsPrimaryKey && field.IsNormal && (field.Name != "CreatedAt" || !field.IsBlank) { - if !field.IsForeignKey || !field.IsBlank || !field.HasDefaultValue { + if !field.IsBlank || field.HasDefaultValue { 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" { diff --git a/callbacks_test.go b/callbacks_test.go index c1a1d5e4..295cbd8f 100644 --- a/callbacks_test.go +++ b/callbacks_test.go @@ -98,12 +98,12 @@ func TestRunCallbacks(t *testing.T) { } DB.Where("Code = ?", "unique_code").First(&p) - if !reflect.DeepEqual(p.GetCallTimes(), []int64{1, 2, 1, 1, 0, 0, 0, 0, 2}) { + if !reflect.DeepEqual(p.GetCallTimes(), []int64{1, 2, 0, 1, 0, 0, 0, 0, 2}) { t.Errorf("After update callbacks values are not saved, %v", p.GetCallTimes()) } DB.Delete(&p) - if !reflect.DeepEqual(p.GetCallTimes(), []int64{1, 2, 1, 1, 0, 0, 1, 1, 2}) { + if !reflect.DeepEqual(p.GetCallTimes(), []int64{1, 2, 0, 1, 0, 0, 1, 1, 2}) { t.Errorf("After delete callbacks should be invoked successfully, %v", p.GetCallTimes()) } diff --git a/migration_test.go b/migration_test.go index d94ec9ec..0257ef28 100644 --- a/migration_test.go +++ b/migration_test.go @@ -292,7 +292,7 @@ func runMigration() { DB.Exec(fmt.Sprintf("drop table %v;", table)) } - values := []interface{}{&Short{}, &ReallyLongThingThatReferencesShort{}, &ReallyLongTableNameToTestMySQLNameLengthLimit{}, &NotSoLongTableName{}, &Product{}, &Email{}, &Address{}, &CreditCard{}, &Company{}, &Role{}, &Language{}, &HNPost{}, &EngadgetPost{}, &Animal{}, &User{}, &JoinTable{}, &Post{}, &Category{}, &Comment{}, &Cat{}, &Dog{}, &Hamster{}, &Toy{}, &ElementWithIgnoredField{}, &Place{}} + values := []interface{}{&Short{}, &ReallyLongThingThatReferencesShort{}, &ReallyLongTableNameToTestMySQLNameLengthLimit{}, &NotSoLongTableName{}, &Product{}, &Email{}, &Address{}, &CreditCard{}, &Company{}, &Role{}, &Language{}, &HNPost{}, &EngadgetPost{}, &Animal{}, &User{}, &JoinTable{}, &Post{}, &Category{}, &Comment{}, &Cat{}, &Dog{}, &Hamster{}, &Toy{}, &ElementWithIgnoredField{}, &Place{}, &NewPerson{}, &NewAddress{}} for _, value := range values { DB.DropTable(value) } diff --git a/update_test.go b/update_test.go index 85d53e5f..e5a3d751 100644 --- a/update_test.go +++ b/update_test.go @@ -419,6 +419,60 @@ func TestUpdatesWithBlankValues(t *testing.T) { } } +type NewAddress struct { + ID int + HouseNumber int + LineOne string +} + +type NewPerson struct { + ID int + Name string + NewAddress NewAddress + + NewAddressID int +} + +func TestAssociatedBlankValues(t *testing.T) { + DB.LogMode(true) + + person1 := NewPerson{ + ID: 1, + Name: "Person", + NewAddress: NewAddress{ + ID: 1, + HouseNumber: 1, + LineOne: "Street One", + }, + } + + DB.Save(&person1) + + person1Update := NewPerson{ + ID: 1, + NewAddress: NewAddress{ + ID: 1, + HouseNumber: 2, + }, + } + DB.Model(&person1Update).Update(person1Update) + + var personGet NewPerson + DB.Preload("NewAddress").Find(&personGet) + + if personGet.NewAddress.LineOne != "Street One" { + t.Errorf("line one should be 'Street One' as it was updated with a blank value. Value is %s", personGet.NewAddress.LineOne) + } + + if personGet.NewAddress.HouseNumber != 2 { + t.Errorf("house number should be 2 following the update. Value is %d", personGet.NewAddress.HouseNumber) + } + + if personGet.Name != "Person" { + t.Errorf("name should be 'Person' as it was updated with a blank value. Value is %s", personGet.Name) + } +} + type ElementWithIgnoredField struct { Id int64 Value string