Make Replace support other associations

This commit is contained in:
Jinzhu 2015-12-25 15:49:41 +08:00
parent 0ce635cc67
commit d57867eb46
2 changed files with 54 additions and 46 deletions

View File

@ -124,7 +124,6 @@ func (association *Association) Delete(values ...interface{}) *Association {
func (association *Association) Replace(values ...interface{}) *Association { func (association *Association) Replace(values ...interface{}) *Association {
relationship := association.Field.Relationship relationship := association.Field.Relationship
scope := association.Scope scope := association.Scope
if relationship.Kind == "many_to_many" {
field := association.Field.Field field := association.Field.Field
oldPrimaryKeys := association.getPrimaryKeys(relationship.AssociationForeignFieldNames, field.Interface()) oldPrimaryKeys := association.getPrimaryKeys(relationship.AssociationForeignFieldNames, field.Interface())
@ -151,7 +150,9 @@ func (association *Association) Replace(values ...interface{}) *Association {
} }
query := scope.NewDB() query := scope.NewDB()
var foreignKeyMap = map[string]string{}
for idx, foreignKey := range relationship.ForeignDBNames { for idx, foreignKey := range relationship.ForeignDBNames {
foreignKeyMap[foreignKey] = ""
if field, ok := scope.FieldByName(relationship.ForeignFieldNames[idx]); ok { if field, ok := scope.FieldByName(relationship.ForeignFieldNames[idx]); ok {
query = query.Where(fmt.Sprintf("%v = ?", scope.Quote(foreignKey)), field.Field.Interface()) query = query.Where(fmt.Sprintf("%v = ?", scope.Quote(foreignKey)), field.Field.Interface())
} }
@ -161,9 +162,11 @@ func (association *Association) Replace(values ...interface{}) *Association {
sql := fmt.Sprintf("%v NOT IN (%v)", toQueryCondition(scope, relationship.AssociationForeignDBNames), toQueryMarks(addedPrimaryKeys)) sql := fmt.Sprintf("%v NOT IN (%v)", toQueryCondition(scope, relationship.AssociationForeignDBNames), toQueryMarks(addedPrimaryKeys))
query = query.Where(sql, toQueryValues(addedPrimaryKeys)...) query = query.Where(sql, toQueryValues(addedPrimaryKeys)...)
} }
if relationship.Kind == "many_to_many" {
association.setErr(relationship.JoinTableHandler.Delete(relationship.JoinTableHandler, query, relationship)) association.setErr(relationship.JoinTableHandler.Delete(relationship.JoinTableHandler, query, relationship))
} else { } else if relationship.Kind == "has_one" || relationship.Kind == "has_many" {
association.setErr(errors.New("replace only support many to many")) query.Update(foreignKeyMap)
} }
return association return association
} }

View File

@ -51,15 +51,20 @@ func TestHasOne(t *testing.T) {
} }
// Replace // Replace
// DB.Model(&post).Association("Category").Replace(&Category{ var category3 = Category{
// Name: "Category 3", Name: "Category 3",
// }) }
DB.Model(&post).Association("Category").Replace(&category3)
// var category3 Category if category3.Id == 0 {
// DB.Model(&post).Related(&category3) t.Errorf("Category should has ID when created with Replace")
// if category3.Name != "Category 3" { }
// t.Errorf("Category should be updated with Replace")
// } var category31 Category
DB.Model(&post).Related(&category31)
if category31.Name != "Category 3" {
t.Errorf("Category should be updated with Replace")
}
// Delete // Delete
// Clear // Clear