From 61f50a429ae61e4d5b9bbad942dae6ee56e8a705 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Thu, 16 Jun 2016 17:58:25 +0800 Subject: [PATCH] Fix preload has one relations --- callback_query_preload.go | 16 ++++++---- migration_test.go | 2 +- preload_test.go | 61 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 7 deletions(-) diff --git a/callback_query_preload.go b/callback_query_preload.go index 16498ba7..b8077ce5 100644 --- a/callback_query_preload.go +++ b/callback_query_preload.go @@ -126,18 +126,22 @@ func (scope *Scope) handleHasOnePreload(field *Field, conditions []interface{}) indirectScopeValue = scope.IndirectValue() ) - for i := 0; i < resultsValue.Len(); i++ { - result := resultsValue.Index(i) - if indirectScopeValue.Kind() == reflect.Slice { - foreignValues := getValueFromFields(result, relation.ForeignFieldNames) - for j := 0; j < indirectScopeValue.Len(); j++ { + if indirectScopeValue.Kind() == reflect.Slice { + for j := 0; j < indirectScopeValue.Len(); j++ { + for i := 0; i < resultsValue.Len(); i++ { + result := resultsValue.Index(i) + foreignValues := getValueFromFields(result, relation.ForeignFieldNames) if indirectValue := indirect(indirectScopeValue.Index(j)); equalAsString(getValueFromFields(indirectValue, relation.AssociationForeignFieldNames), foreignValues) { indirectValue.FieldByName(field.Name).Set(result) break } } - } else { + } + } else { + for i := 0; i < resultsValue.Len(); i++ { + result := resultsValue.Index(i) scope.Err(field.Set(result)) + break } } } diff --git a/migration_test.go b/migration_test.go index b344514a..592dadb7 100644 --- a/migration_test.go +++ b/migration_test.go @@ -381,7 +381,7 @@ func TestMultipleIndexes(t *testing.T) { 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 { t.Errorf("Auto Migrate should not raise any error") } diff --git a/preload_test.go b/preload_test.go index 144d08ad..da3ee38f 100644 --- a/preload_test.go +++ b/preload_test.go @@ -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) { if dialect := os.Getenv("GORM_DIALECT"); dialect == "" || dialect == "sqlite" { return