Fix preload has one relations

This commit is contained in:
Jinzhu 2016-06-16 17:58:25 +08:00
parent 277b4e93b6
commit 61f50a429a
3 changed files with 72 additions and 7 deletions

View File

@ -126,18 +126,22 @@ func (scope *Scope) handleHasOnePreload(field *Field, conditions []interface{})
indirectScopeValue = scope.IndirectValue() indirectScopeValue = scope.IndirectValue()
) )
for i := 0; i < resultsValue.Len(); i++ { if indirectScopeValue.Kind() == reflect.Slice {
result := resultsValue.Index(i) for j := 0; j < indirectScopeValue.Len(); j++ {
if indirectScopeValue.Kind() == reflect.Slice { for i := 0; i < resultsValue.Len(); i++ {
foreignValues := getValueFromFields(result, relation.ForeignFieldNames) result := resultsValue.Index(i)
for j := 0; j < indirectScopeValue.Len(); j++ { foreignValues := getValueFromFields(result, relation.ForeignFieldNames)
if indirectValue := indirect(indirectScopeValue.Index(j)); equalAsString(getValueFromFields(indirectValue, relation.AssociationForeignFieldNames), foreignValues) { if indirectValue := indirect(indirectScopeValue.Index(j)); equalAsString(getValueFromFields(indirectValue, relation.AssociationForeignFieldNames), foreignValues) {
indirectValue.FieldByName(field.Name).Set(result) indirectValue.FieldByName(field.Name).Set(result)
break break
} }
} }
} else { }
} else {
for i := 0; i < resultsValue.Len(); i++ {
result := resultsValue.Index(i)
scope.Err(field.Set(result)) scope.Err(field.Set(result))
break
} }
} }
} }

View File

@ -381,7 +381,7 @@ func TestMultipleIndexes(t *testing.T) {
fmt.Printf("Got error when try to delete table multiple_indexes, %+v\n", err) fmt.Printf("Got error when try to delete table multiple_indexes, %+v\n", err)
} }
DB.Debug().AutoMigrate(&MultipleIndexes{}) DB.AutoMigrate(&MultipleIndexes{})
if err := DB.AutoMigrate(&BigEmail{}).Error; err != nil { if err := DB.AutoMigrate(&BigEmail{}).Error; err != nil {
t.Errorf("Auto Migrate should not raise any error") t.Errorf("Auto Migrate should not raise any error")
} }

View File

@ -727,6 +727,67 @@ func TestNestedPreload11(t *testing.T) {
} }
} }
type LevelC1 struct {
ID uint
Value string
LevelC2ID uint
}
type LevelC2 struct {
ID uint
Value string
LevelC1 LevelC1
}
type LevelC3 struct {
ID uint
Value string
LevelC2ID uint
LevelC2 LevelC2
}
func TestNestedPreload12(t *testing.T) {
DB.DropTableIfExists(&LevelC2{})
DB.DropTableIfExists(&LevelC3{})
DB.DropTableIfExists(&LevelC1{})
if err := DB.AutoMigrate(&LevelC1{}, &LevelC2{}, &LevelC3{}).Error; err != nil {
t.Error(err)
}
level2 := LevelC2{
Value: "c2",
LevelC1: LevelC1{
Value: "c1",
},
}
DB.Create(&level2)
want := []LevelC3{
{
Value: "c3-1",
LevelC2: level2,
}, {
Value: "c3-2",
LevelC2: level2,
},
}
for i := range want {
if err := DB.Create(&want[i]).Error; err != nil {
t.Error(err)
}
}
var got []LevelC3
if err := DB.Preload("LevelC2").Preload("LevelC2.LevelC1").Find(&got).Error; err != nil {
t.Error(err)
}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
}
}
func TestManyToManyPreloadWithMultiPrimaryKeys(t *testing.T) { func TestManyToManyPreloadWithMultiPrimaryKeys(t *testing.T) {
if dialect := os.Getenv("GORM_DIALECT"); dialect == "" || dialect == "sqlite" { if dialect := os.Getenv("GORM_DIALECT"); dialect == "" || dialect == "sqlite" {
return return