Modify struct when update association

This commit is contained in:
Jinzhu 2015-02-24 18:48:48 +08:00
parent 0f08058713
commit eb480cc085
2 changed files with 38 additions and 9 deletions

View File

@ -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"))
}

View File

@ -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")
}
}