From eb480cc08526de02e7b18b504410805ffecd2421 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Tue, 24 Feb 2015 18:48:48 +0800 Subject: [PATCH] Modify struct when update association --- association.go | 28 +++++++++++++++++++++++++--- association_test.go | 19 +++++++++++++------ 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/association.go b/association.go index c8518946..78e09108 100644 --- a/association.go +++ b/association.go @@ -78,8 +78,25 @@ func (association *Association) Delete(values ...interface{}) *Association { relationship.JoinTable, association.Scope.Quote(relationship.ForeignDBName), relationship.JoinTable, association.Scope.Quote(relationship.AssociationForeignDBName)) - association.Scope.db.Model("").Table(relationship.JoinTable). - Where(whereSql, association.PrimaryKey, primaryKeys).Delete("") + if err := association.Scope.db.Model("").Table(relationship.JoinTable). + Where(whereSql, association.PrimaryKey, primaryKeys).Delete("").Error; err == nil { + leftValues := reflect.Zero(association.Field.Field.Type()) + for i := 0; i < association.Field.Field.Len(); i++ { + value := association.Field.Field.Index(i) + if primaryField := association.Scope.New(value.Interface()).PrimaryKeyField(); primaryField != nil { + var included = false + for _, primaryKey := range primaryKeys { + if equalAsString(primaryKey, primaryField.Field.Interface()) { + included = true + } + } + if !included { + leftValues = reflect.Append(leftValues, value) + } + } + } + association.Field.Set(leftValues) + } } else { association.setErr(errors.New("delete only support many to many")) } @@ -94,6 +111,7 @@ func (association *Association) Replace(values ...interface{}) *Association { field := association.Field.Field oldPrimaryKeys := association.getPrimaryKeys(field.Interface()) + association.Field.Set(reflect.Zero(association.Field.Field.Type())) association.Append(values...) newPrimaryKeys := association.getPrimaryKeys(field.Interface()) @@ -130,7 +148,11 @@ func (association *Association) Clear() *Association { scope := association.Scope if relationship.Kind == "many_to_many" { whereSql := fmt.Sprintf("%v.%v = ?", relationship.JoinTable, scope.Quote(relationship.ForeignDBName)) - scope.db.Model("").Table(relationship.JoinTable).Where(whereSql, association.PrimaryKey).Delete("") + if err := scope.db.Model("").Table(relationship.JoinTable).Where(whereSql, association.PrimaryKey).Delete("").Error; err == nil { + association.Field.Set(reflect.Zero(association.Field.Field.Type())) + } else { + association.setErr(err) + } } else { association.setErr(errors.New("clear only support many to many")) } diff --git a/association_test.go b/association_test.go index 201eed53..fb73d443 100644 --- a/association_test.go +++ b/association_test.go @@ -1,6 +1,9 @@ package gorm_test -import "testing" +import ( + "os" + "testing" +) func TestHasOneAndHasManyAssociation(t *testing.T) { DB.DropTable(Category{}) @@ -172,11 +175,15 @@ func TestManyToMany(t *testing.T) { } // Delete + user.Languages = []Language{} + DB.Model(&user).Association("Languages").Find(&user.Languages) + var language Language DB.Where("name = ?", "EE").First(&language) DB.Model(&user).Association("Languages").Delete(language, &language) - if DB.Model(&user).Association("Languages").Count() != len(totalLanguages)-1 { + if DB.Model(&user).Association("Languages").Count() != len(totalLanguages)-1 || len(user.Languages) != len(totalLanguages)-1 { t.Errorf("Relations should be deleted with Delete") + os.Exit(1) } if DB.Where("name = ?", "EE").First(&Language{}).RecordNotFound() { t.Errorf("Language EE should not be deleted") @@ -189,7 +196,7 @@ func TestManyToMany(t *testing.T) { DB.Save(&user2) DB.Model(&user).Association("Languages").Delete(languages, &languages) - if DB.Model(&user).Association("Languages").Count() != len(totalLanguages)-3 { + if DB.Model(&user).Association("Languages").Count() != len(totalLanguages)-3 || len(user.Languages) != len(totalLanguages)-3 { t.Errorf("Relations should be deleted with Delete") } @@ -201,18 +208,18 @@ func TestManyToMany(t *testing.T) { var languageB Language DB.Where("name = ?", "BB").First(&languageB) DB.Model(&user).Association("Languages").Replace(languageB) - if DB.Model(&user).Association("Languages").Count() != 1 { + if len(user.Languages) != 1 || DB.Model(&user).Association("Languages").Count() != 1 { t.Errorf("Relations should be replaced") } DB.Model(&user).Association("Languages").Replace(&[]Language{{Name: "FF"}, {Name: "JJ"}}) - if DB.Model(&user).Association("Languages").Count() != len([]string{"FF", "JJ"}) { + if len(user.Languages) != 2 || DB.Model(&user).Association("Languages").Count() != len([]string{"FF", "JJ"}) { t.Errorf("Relations should be replaced") } // Clear DB.Model(&user).Association("Languages").Clear() - if DB.Model(&user).Association("Languages").Count() != 0 { + if len(user.Languages) != 0 || DB.Model(&user).Association("Languages").Count() != 0 { t.Errorf("Relations should be cleared") } }