From c85f00bcd2b78d23ec67921b51adc5cec4f878dd Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Fri, 25 Dec 2015 17:09:20 +0800 Subject: [PATCH] Add BelongsTo support for association Delete --- association.go | 22 ++++++++++++++++++---- association_test.go | 17 ++++++++++++----- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/association.go b/association.go index 82e39950..017e739c 100644 --- a/association.go +++ b/association.go @@ -83,17 +83,19 @@ func (association *Association) Append(values ...interface{}) *Association { func (association *Association) Delete(values ...interface{}) *Association { scope := association.Scope + query := scope.NewDB() relationship := association.Field.Relationship // many to many if relationship.Kind == "many_to_many" { - query := scope.NewDB() + // current value's foreign keys for idx, foreignKey := range relationship.ForeignDBNames { if field, ok := scope.FieldByName(relationship.ForeignFieldNames[idx]); ok { query = query.Where(fmt.Sprintf("%v = ?", scope.Quote(foreignKey)), field.Field.Interface()) } } + // deleting value's foreign keys primaryKeys := association.getPrimaryKeys(relationship.AssociationForeignFieldNames, values...) sql := fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relationship.AssociationForeignDBNames), toQueryMarks(primaryKeys)) query = query.Where(sql, toQueryValues(primaryKeys)...) @@ -116,7 +118,19 @@ func (association *Association) Delete(values ...interface{}) *Association { association.Field.Set(leftValues) } } else { - association.setErr(errors.New("delete only support many to many")) + association.Field.Set(reflect.Zero(association.Field.Field.Type())) + + if relationship.Kind == "belongs_to" { + var foreignKeyMap = map[string]interface{}{} + for _, foreignKey := range relationship.ForeignDBNames { + foreignKeyMap[foreignKey] = nil + } + primaryKeys := association.getPrimaryKeys(relationship.AssociationForeignFieldNames, values...) + sql := fmt.Sprintf("%v IN (%v)", toQueryCondition(scope, relationship.ForeignDBNames), toQueryMarks(primaryKeys)) + query.Model(scope.Value).Where(sql, toQueryValues(primaryKeys)...).Update(foreignKeyMap) + } else if relationship.Kind == "has_one" || relationship.Kind == "has_many" { + // query.Model(association.Field).UpdateColumn(foreignKeyMap) + } } return association } @@ -150,9 +164,9 @@ func (association *Association) Replace(values ...interface{}) *Association { } query := scope.NewDB() - var foreignKeyMap = map[string]string{} + var foreignKeyMap = map[string]interface{}{} for idx, foreignKey := range relationship.ForeignDBNames { - foreignKeyMap[foreignKey] = "" + foreignKeyMap[foreignKey] = nil if field, ok := scope.FieldByName(relationship.ForeignFieldNames[idx]); ok { query = query.Where(fmt.Sprintf("%v = ?", scope.Quote(foreignKey)), field.Field.Interface()) } diff --git a/association_test.go b/association_test.go index 32f1e6b2..66844c34 100644 --- a/association_test.go +++ b/association_test.go @@ -5,15 +5,14 @@ import ( "testing" ) -func TestHasOne(t *testing.T) { +func TestBelongsTo(t *testing.T) { DB.DropTable(Category{}, Post{}) DB.CreateTable(Category{}, Post{}) post := Post{ - Title: "post 1", - Body: "body 1", - Category: Category{Name: "Category 1"}, - MainCategory: Category{Name: "Main Category 1"}, + Title: "post 1", + Body: "body 1", + Category: Category{Name: "Category 1"}, } if err := DB.Save(&post).Error; err != nil { @@ -67,6 +66,14 @@ func TestHasOne(t *testing.T) { } // Delete + DB.Model(&post).Association("Category").Delete(&category3) + + var category41 Category + DB.Model(&post).Related(&category41) + if category41.Name != "" { + t.Errorf("Category should be deleted with Delete") + } + // Clear }