Fix Replace has one/many associations

This commit is contained in:
Jinzhu 2016-10-20 13:27:26 +08:00
parent 5d853fc53c
commit a667ab8427
3 changed files with 21 additions and 4 deletions

View File

@ -68,26 +68,28 @@ func (association *Association) Replace(values ...interface{}) *Association {
// Delete Relations except new created // Delete Relations except new created
if len(values) > 0 { if len(values) > 0 {
var associationForeignFieldNames []string var associationForeignFieldNames, associationForeignDBNames []string
if relationship.Kind == "many_to_many" { if relationship.Kind == "many_to_many" {
// if many to many relations, get association fields name from association foreign keys // if many to many relations, get association fields name from association foreign keys
associationScope := scope.New(reflect.New(field.Type()).Interface()) associationScope := scope.New(reflect.New(field.Type()).Interface())
for _, dbName := range relationship.AssociationForeignFieldNames { for idx, dbName := range relationship.AssociationForeignFieldNames {
if field, ok := associationScope.FieldByName(dbName); ok { if field, ok := associationScope.FieldByName(dbName); ok {
associationForeignFieldNames = append(associationForeignFieldNames, field.Name) associationForeignFieldNames = append(associationForeignFieldNames, field.Name)
associationForeignDBNames = append(associationForeignDBNames, relationship.AssociationForeignDBNames[idx])
} }
} }
} else { } else {
// If other relations, use primary keys // If has one/many relations, use primary keys
for _, field := range scope.New(reflect.New(field.Type()).Interface()).PrimaryFields() { for _, field := range scope.New(reflect.New(field.Type()).Interface()).PrimaryFields() {
associationForeignFieldNames = append(associationForeignFieldNames, field.Name) associationForeignFieldNames = append(associationForeignFieldNames, field.Name)
associationForeignDBNames = append(associationForeignDBNames, field.DBName)
} }
} }
newPrimaryKeys := scope.getColumnAsArray(associationForeignFieldNames, field.Interface()) newPrimaryKeys := scope.getColumnAsArray(associationForeignFieldNames, field.Interface())
if len(newPrimaryKeys) > 0 { if len(newPrimaryKeys) > 0 {
sql := fmt.Sprintf("%v NOT IN (%v)", toQueryCondition(scope, relationship.AssociationForeignDBNames), toQueryMarks(newPrimaryKeys)) sql := fmt.Sprintf("%v NOT IN (%v)", toQueryCondition(scope, associationForeignDBNames), toQueryMarks(newPrimaryKeys))
newDB = newDB.Where(sql, toQueryValues(newPrimaryKeys)...) newDB = newDB.Where(sql, toQueryValues(newPrimaryKeys)...)
} }
} }

View File

@ -872,3 +872,15 @@ func TestLongForeignKey(t *testing.T) {
func TestLongForeignKeyWithShortDest(t *testing.T) { func TestLongForeignKeyWithShortDest(t *testing.T) {
testForeignKey(t, &ReallyLongThingThatReferencesShort{}, "ShortID", &Short{}, "ID") testForeignKey(t, &ReallyLongThingThatReferencesShort{}, "ShortID", &Short{}, "ID")
} }
func TestHasManyChildrenWithOneStruct(t *testing.T) {
category := Category{
Name: "main",
Categories: []Category{
{Name: "sub1"},
{Name: "sub2"},
},
}
DB.Save(&category)
}

View File

@ -180,6 +180,9 @@ type Post struct {
type Category struct { type Category struct {
gorm.Model gorm.Model
Name string Name string
Categories []Category
CategoryID *uint
} }
type Comment struct { type Comment struct {