10 "github.com/jinzhu/gorm"
13 func getPreloadUser(name string) *User {
14 return getPreparedUser(name, "Preload")
17 func checkUserHasPreloadData(user User, t *testing.T) {
18 u := getPreloadUser(user.Name)
19 if user.BillingAddress.Address1 != u.BillingAddress.Address1 {
20 t.Error("Failed to preload user's BillingAddress")
23 if user.ShippingAddress.Address1 != u.ShippingAddress.Address1 {
24 t.Error("Failed to preload user's ShippingAddress")
27 if user.CreditCard.Number != u.CreditCard.Number {
28 t.Error("Failed to preload user's CreditCard")
31 if user.Company.Name != u.Company.Name {
32 t.Error("Failed to preload user's Company")
35 if len(user.Emails) != len(u.Emails) {
36 t.Error("Failed to preload user's Emails")
39 for _, e1 := range u.Emails {
40 for _, e2 := range user.Emails {
41 if e1.Email == e2.Email {
47 if found != len(u.Emails) {
48 t.Error("Failed to preload user's email details")
53 func TestPreload(t *testing.T) {
54 user1 := getPreloadUser("user1")
57 preloadDB := DB.Where("role = ?", "Preload").Preload("BillingAddress").Preload("ShippingAddress").
58 Preload("CreditCard").Preload("Emails").Preload("Company")
61 checkUserHasPreloadData(user, t)
63 user2 := getPreloadUser("user2")
66 user3 := getPreloadUser("user3")
70 preloadDB.Find(&users)
72 for _, user := range users {
73 checkUserHasPreloadData(user, t)
77 preloadDB.Find(&users2)
79 for _, user := range users2 {
80 checkUserHasPreloadData(*user, t)
84 preloadDB.Preload("Emails", "email = ?", user3.Emails[0].Email).Find(&users3)
86 for _, user := range users3 {
87 if user.Name == user3.Name {
88 if len(user.Emails) != 1 {
89 t.Errorf("should only preload one emails for user3 when with condition")
91 } else if len(user.Emails) != 0 {
92 t.Errorf("should not preload any emails for other users when with condition")
93 } else if user.Emails == nil {
94 t.Errorf("should return an empty slice to indicate zero results")
99 func TestAutoPreload(t *testing.T) {
100 user1 := getPreloadUser("auto_user1")
103 preloadDB := DB.Set("gorm:auto_preload", true).Where("role = ?", "Preload")
105 preloadDB.Find(&user)
106 checkUserHasPreloadData(user, t)
108 user2 := getPreloadUser("auto_user2")
112 preloadDB.Find(&users)
114 for _, user := range users {
115 checkUserHasPreloadData(user, t)
119 preloadDB.Find(&users2)
121 for _, user := range users2 {
122 checkUserHasPreloadData(*user, t)
126 func TestAutoPreloadFalseDoesntPreload(t *testing.T) {
127 user1 := getPreloadUser("auto_user1")
130 preloadDB := DB.Set("gorm:auto_preload", false).Where("role = ?", "Preload")
132 preloadDB.Find(&user)
134 if user.BillingAddress.Address1 != "" {
135 t.Error("AutoPreload was set to fasle, but still fetched data")
138 user2 := getPreloadUser("auto_user2")
142 preloadDB.Find(&users)
144 for _, user := range users {
145 if user.BillingAddress.Address1 != "" {
146 t.Error("AutoPreload was set to fasle, but still fetched data")
151 func TestNestedPreload1(t *testing.T) {
169 DB.DropTableIfExists(&Level3{})
170 DB.DropTableIfExists(&Level2{})
171 DB.DropTableIfExists(&Level1{})
172 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
176 want := Level3{Level2: Level2{Level1: Level1{Value: "value"}}}
177 if err := DB.Create(&want).Error; err != nil {
182 if err := DB.Preload("Level2").Preload("Level2.Level1").Find(&got).Error; err != nil {
186 if !reflect.DeepEqual(got, want) {
187 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
190 if err := DB.Preload("Level2").Preload("Level2.Level1").Find(&got, "name = ?", "not_found").Error; err != gorm.ErrRecordNotFound {
195 func TestNestedPreload2(t *testing.T) {
213 DB.DropTableIfExists(&Level3{})
214 DB.DropTableIfExists(&Level2{})
215 DB.DropTableIfExists(&Level1{})
216 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
235 if err := DB.Create(&want).Error; err != nil {
240 if err := DB.Preload("Level2s.Level1s").Find(&got).Error; err != nil {
244 if !reflect.DeepEqual(got, want) {
245 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
249 func TestNestedPreload3(t *testing.T) {
267 DB.DropTableIfExists(&Level3{})
268 DB.DropTableIfExists(&Level2{})
269 DB.DropTableIfExists(&Level1{})
270 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
276 {Level1: Level1{Value: "value1"}},
277 {Level1: Level1{Value: "value2"}},
280 if err := DB.Create(&want).Error; err != nil {
285 if err := DB.Preload("Level2s.Level1").Find(&got).Error; err != nil {
289 if !reflect.DeepEqual(got, want) {
290 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
294 func TestNestedPreload4(t *testing.T) {
312 DB.DropTableIfExists(&Level3{})
313 DB.DropTableIfExists(&Level2{})
314 DB.DropTableIfExists(&Level1{})
315 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
327 if err := DB.Create(&want).Error; err != nil {
332 if err := DB.Preload("Level2.Level1s").Find(&got).Error; err != nil {
336 if !reflect.DeepEqual(got, want) {
337 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
342 func TestNestedPreload5(t *testing.T) {
360 DB.DropTableIfExists(&Level3{})
361 DB.DropTableIfExists(&Level2{})
362 DB.DropTableIfExists(&Level1{})
363 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
367 want := make([]Level3, 2)
368 want[0] = Level3{Level2: Level2{Level1: Level1{Value: "value"}}}
369 if err := DB.Create(&want[0]).Error; err != nil {
372 want[1] = Level3{Level2: Level2{Level1: Level1{Value: "value2"}}}
373 if err := DB.Create(&want[1]).Error; err != nil {
378 if err := DB.Preload("Level2").Preload("Level2.Level1").Find(&got).Error; err != nil {
382 if !reflect.DeepEqual(got, want) {
383 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
387 func TestNestedPreload6(t *testing.T) {
405 DB.DropTableIfExists(&Level3{})
406 DB.DropTableIfExists(&Level2{})
407 DB.DropTableIfExists(&Level1{})
408 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
412 want := make([]Level3, 2)
428 if err := DB.Create(&want[0]).Error; err != nil {
447 if err := DB.Create(&want[1]).Error; err != nil {
452 if err := DB.Preload("Level2s.Level1s").Find(&got).Error; err != nil {
456 if !reflect.DeepEqual(got, want) {
457 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
461 func TestNestedPreload7(t *testing.T) {
479 DB.DropTableIfExists(&Level3{})
480 DB.DropTableIfExists(&Level2{})
481 DB.DropTableIfExists(&Level1{})
482 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
486 want := make([]Level3, 2)
489 {Level1: Level1{Value: "value1"}},
490 {Level1: Level1{Value: "value2"}},
493 if err := DB.Create(&want[0]).Error; err != nil {
499 {Level1: Level1{Value: "value3"}},
500 {Level1: Level1{Value: "value4"}},
503 if err := DB.Create(&want[1]).Error; err != nil {
508 if err := DB.Preload("Level2s.Level1").Find(&got).Error; err != nil {
512 if !reflect.DeepEqual(got, want) {
513 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
517 func TestNestedPreload8(t *testing.T) {
535 DB.DropTableIfExists(&Level3{})
536 DB.DropTableIfExists(&Level2{})
537 DB.DropTableIfExists(&Level1{})
538 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
542 want := make([]Level3, 2)
551 if err := DB.Create(&want[0]).Error; err != nil {
562 if err := DB.Create(&want[1]).Error; err != nil {
567 if err := DB.Preload("Level2.Level1s").Find(&got).Error; err != nil {
571 if !reflect.DeepEqual(got, want) {
572 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
576 func TestNestedPreload9(t *testing.T) {
607 DB.DropTableIfExists(&Level3{})
608 DB.DropTableIfExists(&Level2{})
609 DB.DropTableIfExists(&Level2_1{})
610 DB.DropTableIfExists(&Level1{})
611 DB.DropTableIfExists(&Level0{})
612 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}, &Level2_1{}, &Level0{}).Error; err != nil {
616 want := make([]Level3, 2)
628 Level0s: []Level0{{Value: "Level0-1"}},
632 Level0s: []Level0{{Value: "Level0-2"}},
637 if err := DB.Create(&want[0]).Error; err != nil {
660 if err := DB.Create(&want[1]).Error; err != nil {
665 if err := DB.Preload("Level2").Preload("Level2.Level1s").Preload("Level2_1").Preload("Level2_1.Level1s").Preload("Level2_1.Level1s.Level0s").Find(&got).Error; err != nil {
669 if !reflect.DeepEqual(got, want) {
670 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
674 type LevelA1 struct {
679 type LevelA2 struct {
685 type LevelA3 struct {
688 LevelA1ID sql.NullInt64
690 LevelA2ID sql.NullInt64
694 func TestNestedPreload10(t *testing.T) {
695 DB.DropTableIfExists(&LevelA3{})
696 DB.DropTableIfExists(&LevelA2{})
697 DB.DropTableIfExists(&LevelA1{})
699 if err := DB.AutoMigrate(&LevelA1{}, &LevelA2{}, &LevelA3{}).Error; err != nil {
703 levelA1 := &LevelA1{Value: "foo"}
704 if err := DB.Save(levelA1).Error; err != nil {
711 LevelA3s: []*LevelA3{
720 LevelA3s: []*LevelA3{},
723 for _, levelA2 := range want {
724 if err := DB.Save(levelA2).Error; err != nil {
730 if err := DB.Preload("LevelA3s.LevelA1").Find(&got).Error; err != nil {
734 if !reflect.DeepEqual(got, want) {
735 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
739 type LevelB1 struct {
745 type LevelB2 struct {
750 type LevelB3 struct {
753 LevelB1ID sql.NullInt64
755 LevelB2s []*LevelB2 `gorm:"many2many:levelb1_levelb3_levelb2s"`
758 func TestNestedPreload11(t *testing.T) {
759 DB.DropTableIfExists(&LevelB2{})
760 DB.DropTableIfExists(&LevelB3{})
761 DB.DropTableIfExists(&LevelB1{})
762 if err := DB.AutoMigrate(&LevelB1{}, &LevelB2{}, &LevelB3{}).Error; err != nil {
766 levelB1 := &LevelB1{Value: "foo"}
767 if err := DB.Create(levelB1).Error; err != nil {
773 LevelB1ID: sql.NullInt64{Valid: true, Int64: int64(levelB1.ID)},
775 if err := DB.Create(levelB3).Error; err != nil {
778 levelB1.LevelB3s = []*LevelB3{levelB3}
780 want := []*LevelB1{levelB1}
782 if err := DB.Preload("LevelB3s.LevelB2s").Find(&got).Error; err != nil {
786 if !reflect.DeepEqual(got, want) {
787 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
791 type LevelC1 struct {
797 type LevelC2 struct {
803 type LevelC3 struct {
810 func TestNestedPreload12(t *testing.T) {
811 DB.DropTableIfExists(&LevelC2{})
812 DB.DropTableIfExists(&LevelC3{})
813 DB.DropTableIfExists(&LevelC1{})
814 if err := DB.AutoMigrate(&LevelC1{}, &LevelC2{}, &LevelC3{}).Error; err != nil {
836 for i := range want {
837 if err := DB.Create(&want[i]).Error; err != nil {
843 if err := DB.Preload("LevelC2").Preload("LevelC2.LevelC1").Find(&got).Error; err != nil {
847 if !reflect.DeepEqual(got, want) {
848 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
852 func TestManyToManyPreloadWithMultiPrimaryKeys(t *testing.T) {
853 if dialect := os.Getenv("GORM_DIALECT"); dialect == "" || dialect == "sqlite" || dialect == "mssql" {
859 ID uint `gorm:"primary_key;"`
860 LanguageCode string `gorm:"primary_key"`
864 ID uint `gorm:"primary_key;"`
865 LanguageCode string `gorm:"primary_key"`
867 Level1s []Level1 `gorm:"many2many:levels;"`
871 DB.DropTableIfExists(&Level2{})
872 DB.DropTableIfExists(&Level1{})
873 DB.DropTableIfExists("levels")
875 if err := DB.AutoMigrate(&Level2{}, &Level1{}).Error; err != nil {
879 want := Level2{Value: "Bob", LanguageCode: "ru", Level1s: []Level1{
880 {Value: "ru", LanguageCode: "ru"},
881 {Value: "en", LanguageCode: "en"},
883 if err := DB.Save(&want).Error; err != nil {
887 want2 := Level2{Value: "Tom", LanguageCode: "zh", Level1s: []Level1{
888 {Value: "zh", LanguageCode: "zh"},
889 {Value: "de", LanguageCode: "de"},
891 if err := DB.Save(&want2).Error; err != nil {
896 if err := DB.Preload("Level1s").Find(&got, "value = ?", "Bob").Error; err != nil {
900 if !reflect.DeepEqual(got, want) {
901 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
905 if err := DB.Preload("Level1s").Find(&got2, "value = ?", "Tom").Error; err != nil {
909 if !reflect.DeepEqual(got2, want2) {
910 t.Errorf("got %s; want %s", toJSONString(got2), toJSONString(want2))
914 if err := DB.Preload("Level1s").Find(&got3, "value IN (?)", []string{"Bob", "Tom"}).Error; err != nil {
918 if !reflect.DeepEqual(got3, []Level2{got, got2}) {
919 t.Errorf("got %s; want %s", toJSONString(got3), toJSONString([]Level2{got, got2}))
923 if err := DB.Preload("Level1s", "value IN (?)", []string{"zh", "ru"}).Find(&got4, "value IN (?)", []string{"Bob", "Tom"}).Error; err != nil {
929 DB.First(&ruLevel1, "value = ?", "ru")
930 DB.First(&zhLevel1, "value = ?", "zh")
932 got.Level1s = []Level1{ruLevel1}
933 got2.Level1s = []Level1{zhLevel1}
934 if !reflect.DeepEqual(got4, []Level2{got, got2}) {
935 t.Errorf("got %s; want %s", toJSONString(got4), toJSONString([]Level2{got, got2}))
938 if err := DB.Preload("Level1s").Find(&got4, "value IN (?)", []string{"non-existing"}).Error; err != nil {
943 func TestManyToManyPreloadForNestedPointer(t *testing.T) {
952 Level1s []*Level1 `gorm:"many2many:levels;"`
957 Level2ID sql.NullInt64
962 DB.DropTableIfExists(&Level3{})
963 DB.DropTableIfExists(&Level2{})
964 DB.DropTableIfExists(&Level1{})
965 DB.DropTableIfExists("levels")
967 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
981 if err := DB.Save(&want).Error; err != nil {
995 if err := DB.Save(&want2).Error; err != nil {
1000 if err := DB.Preload("Level2.Level1s").Find(&got, "value = ?", "Bob").Error; err != nil {
1004 if !reflect.DeepEqual(got, want) {
1005 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
1009 if err := DB.Preload("Level2.Level1s").Find(&got2, "value = ?", "Tom").Error; err != nil {
1013 if !reflect.DeepEqual(got2, want2) {
1014 t.Errorf("got %s; want %s", toJSONString(got2), toJSONString(want2))
1018 if err := DB.Preload("Level2.Level1s").Find(&got3, "value IN (?)", []string{"Bob", "Tom"}).Error; err != nil {
1022 if !reflect.DeepEqual(got3, []Level3{got, got2}) {
1023 t.Errorf("got %s; want %s", toJSONString(got3), toJSONString([]Level3{got, got2}))
1027 if err := DB.Preload("Level2.Level1s", "value IN (?)", []string{"zh", "ru"}).Find(&got4, "value IN (?)", []string{"Bob", "Tom"}).Error; err != nil {
1032 DB.Preload("Level2.Level1s").Find(&got5, "value = ?", "bogus")
1036 DB.First(&ruLevel1, "value = ?", "ru")
1037 DB.First(&zhLevel1, "value = ?", "zh")
1039 got.Level2.Level1s = []*Level1{&ruLevel1}
1040 got2.Level2.Level1s = []*Level1{&zhLevel1}
1041 if !reflect.DeepEqual(got4, []Level3{got, got2}) {
1042 t.Errorf("got %s; want %s", toJSONString(got4), toJSONString([]Level3{got, got2}))
1046 func TestNestedManyToManyPreload(t *testing.T) {
1055 Level1s []*Level1 `gorm:"many2many:level1_level2;"`
1060 Level2s []Level2 `gorm:"many2many:level2_level3;"`
1064 DB.DropTableIfExists(&Level1{})
1065 DB.DropTableIfExists(&Level2{})
1066 DB.DropTableIfExists(&Level3{})
1067 DB.DropTableIfExists("level1_level2")
1068 DB.DropTableIfExists("level2_level3")
1070 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
1093 if err := DB.Save(&want).Error; err != nil {
1098 if err := DB.Preload("Level2s").Preload("Level2s.Level1s").Find(&got, "value = ?", "Level3").Error; err != nil {
1102 if !reflect.DeepEqual(got, want) {
1103 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
1106 if err := DB.Preload("Level2s.Level1s").Find(&got, "value = ?", "not_found").Error; err != gorm.ErrRecordNotFound {
1111 func TestNestedManyToManyPreload2(t *testing.T) {
1120 Level1s []*Level1 `gorm:"many2many:level1_level2;"`
1125 Level2ID sql.NullInt64
1130 DB.DropTableIfExists(&Level1{})
1131 DB.DropTableIfExists(&Level2{})
1132 DB.DropTableIfExists(&Level3{})
1133 DB.DropTableIfExists("level1_level2")
1135 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
1150 if err := DB.Save(&want).Error; err != nil {
1155 if err := DB.Preload("Level2.Level1s").Find(&got, "value = ?", "Level3").Error; err != nil {
1159 if !reflect.DeepEqual(got, want) {
1160 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
1163 if err := DB.Preload("Level2.Level1s").Find(&got, "value = ?", "not_found").Error; err != gorm.ErrRecordNotFound {
1168 func TestNestedManyToManyPreload3(t *testing.T) {
1177 Level1s []*Level1 `gorm:"many2many:level1_level2;"`
1182 Level2ID sql.NullInt64
1187 DB.DropTableIfExists(&Level1{})
1188 DB.DropTableIfExists(&Level2{})
1189 DB.DropTableIfExists(&Level3{})
1190 DB.DropTableIfExists("level1_level2")
1192 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
1196 level1Zh := &Level1{Value: "zh"}
1197 level1Ru := &Level1{Value: "ru"}
1198 level1En := &Level1{Value: "en"}
1202 Level1s: []*Level1{level1Zh, level1Ru},
1207 Level1s: []*Level1{level1Zh, level1En},
1225 for _, want := range wants {
1226 if err := DB.Save(&want).Error; err != nil {
1232 if err := DB.Preload("Level2.Level1s", func(db *gorm.DB) *gorm.DB {
1233 return db.Order("level1.id ASC")
1234 }).Find(&gots).Error; err != nil {
1238 if !reflect.DeepEqual(gots, wants) {
1239 t.Errorf("got %s; want %s", toJSONString(gots), toJSONString(wants))
1243 func TestNestedManyToManyPreload3ForStruct(t *testing.T) {
1252 Level1s []Level1 `gorm:"many2many:level1_level2;"`
1257 Level2ID sql.NullInt64
1262 DB.DropTableIfExists(&Level1{})
1263 DB.DropTableIfExists(&Level2{})
1264 DB.DropTableIfExists(&Level3{})
1265 DB.DropTableIfExists("level1_level2")
1267 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
1271 level1Zh := Level1{Value: "zh"}
1272 level1Ru := Level1{Value: "ru"}
1273 level1En := Level1{Value: "en"}
1277 Level1s: []Level1{level1Zh, level1Ru},
1282 Level1s: []Level1{level1Zh, level1En},
1300 for _, want := range wants {
1301 if err := DB.Save(&want).Error; err != nil {
1307 if err := DB.Preload("Level2.Level1s", func(db *gorm.DB) *gorm.DB {
1308 return db.Order("level1.id ASC")
1309 }).Find(&gots).Error; err != nil {
1313 if !reflect.DeepEqual(gots, wants) {
1314 t.Errorf("got %s; want %s", toJSONString(gots), toJSONString(wants))
1318 func TestNestedManyToManyPreload4(t *testing.T) {
1333 Level3s []*Level3 `gorm:"many2many:level2_level3;"`
1338 Level2s []*Level2 `gorm:"many2many:level1_level2;"`
1342 DB.DropTableIfExists(&Level1{})
1343 DB.DropTableIfExists(&Level2{})
1344 DB.DropTableIfExists(&Level3{})
1345 DB.DropTableIfExists(&Level4{})
1346 DB.DropTableIfExists("level1_level2")
1347 DB.DropTableIfExists("level2_level3")
1351 Level2s: []*Level2{{
1353 Level3s: []*Level3{{
1355 Level4s: []*Level4{{
1362 if err := DB.AutoMigrate(&Level4{}, &Level3{}, &Level2{}, &Level1{}).Error; err != nil {
1366 if err := DB.Save(&dummy).Error; err != nil {
1371 if err := DB.Preload("Level2s").Preload("Level2s.Level3s").Preload("Level2s.Level3s.Level4s").First(&level1).Error; err != nil {
1376 func TestManyToManyPreloadForPointer(t *testing.T) {
1385 Level1s []*Level1 `gorm:"many2many:levels;"`
1389 DB.DropTableIfExists(&Level2{})
1390 DB.DropTableIfExists(&Level1{})
1391 DB.DropTableIfExists("levels")
1393 if err := DB.AutoMigrate(&Level2{}, &Level1{}).Error; err != nil {
1397 want := Level2{Value: "Bob", Level1s: []*Level1{
1401 if err := DB.Save(&want).Error; err != nil {
1405 want2 := Level2{Value: "Tom", Level1s: []*Level1{
1409 if err := DB.Save(&want2).Error; err != nil {
1414 if err := DB.Preload("Level1s").Find(&got, "value = ?", "Bob").Error; err != nil {
1418 if !reflect.DeepEqual(got, want) {
1419 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
1423 if err := DB.Preload("Level1s").Find(&got2, "value = ?", "Tom").Error; err != nil {
1427 if !reflect.DeepEqual(got2, want2) {
1428 t.Errorf("got %s; want %s", toJSONString(got2), toJSONString(want2))
1432 if err := DB.Preload("Level1s").Find(&got3, "value IN (?)", []string{"Bob", "Tom"}).Error; err != nil {
1436 if !reflect.DeepEqual(got3, []Level2{got, got2}) {
1437 t.Errorf("got %s; want %s", toJSONString(got3), toJSONString([]Level2{got, got2}))
1441 if err := DB.Preload("Level1s", "value IN (?)", []string{"zh", "ru"}).Find(&got4, "value IN (?)", []string{"Bob", "Tom"}).Error; err != nil {
1446 DB.Preload("Level1s").First(&got5, "value = ?", "bogus")
1450 DB.First(&ruLevel1, "value = ?", "ru")
1451 DB.First(&zhLevel1, "value = ?", "zh")
1453 got.Level1s = []*Level1{&ruLevel1}
1454 got2.Level1s = []*Level1{&zhLevel1}
1455 if !reflect.DeepEqual(got4, []Level2{got, got2}) {
1456 t.Errorf("got %s; want %s", toJSONString(got4), toJSONString([]Level2{got, got2}))
1460 func TestNilPointerSlice(t *testing.T) {
1480 DB.DropTableIfExists(&Level3{})
1481 DB.DropTableIfExists(&Level2{})
1482 DB.DropTableIfExists(&Level1{})
1484 if err := DB.AutoMigrate(&Level3{}, &Level2{}, &Level1{}).Error; err != nil {
1497 if err := DB.Save(&want).Error; err != nil {
1505 if err := DB.Save(&want2).Error; err != nil {
1510 if err := DB.Preload("Level2").Preload("Level2.Level3").Find(&got).Error; err != nil {
1515 t.Errorf("got %v items, expected 2", len(got))
1518 if !reflect.DeepEqual(got[0], want) && !reflect.DeepEqual(got[1], want) {
1519 t.Errorf("got %s; want array containing %s", toJSONString(got), toJSONString(want))
1522 if !reflect.DeepEqual(got[0], want2) && !reflect.DeepEqual(got[1], want2) {
1523 t.Errorf("got %s; want array containing %s", toJSONString(got), toJSONString(want2))
1527 func TestNilPointerSlice2(t *testing.T) {
1534 Level4ID sql.NullInt64 `sql:"index"`
1539 Level3s []*Level3 `gorm:"many2many:level2_level3s"`
1543 Level2ID sql.NullInt64 `sql:"index"`
1548 DB.DropTableIfExists(new(Level4))
1549 DB.DropTableIfExists(new(Level3))
1550 DB.DropTableIfExists(new(Level2))
1551 DB.DropTableIfExists(new(Level1))
1553 if err := DB.AutoMigrate(new(Level4), new(Level3), new(Level2), new(Level1)).Error; err != nil {
1558 if err := DB.Save(want).Error; err != nil {
1563 err := DB.Preload("Level2.Level3s.Level4").Last(&got).Error
1568 if !reflect.DeepEqual(got, want) {
1569 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
1573 func TestPrefixedPreloadDuplication(t *testing.T) {
1588 Level3ID sql.NullInt64 `sql:"index"`
1594 Level2ID sql.NullInt64 `sql:"index"`
1599 DB.DropTableIfExists(new(Level3))
1600 DB.DropTableIfExists(new(Level4))
1601 DB.DropTableIfExists(new(Level2))
1602 DB.DropTableIfExists(new(Level1))
1604 if err := DB.AutoMigrate(new(Level3), new(Level4), new(Level2), new(Level1)).Error; err != nil {
1609 if err := DB.Save(lvl).Error; err != nil {
1613 sublvl1 := &Level4{Level3ID: lvl.ID}
1614 if err := DB.Save(sublvl1).Error; err != nil {
1617 sublvl2 := &Level4{Level3ID: lvl.ID}
1618 if err := DB.Save(sublvl2).Error; err != nil {
1622 lvl.Level4s = []*Level4{sublvl1, sublvl2}
1629 if err := DB.Save(&want1).Error; err != nil {
1638 if err := DB.Save(&want2).Error; err != nil {
1642 want := []Level1{want1, want2}
1645 err := DB.Preload("Level2.Level3.Level4s").Find(&got).Error
1650 if !reflect.DeepEqual(got, want) {
1651 t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
1655 func TestPreloadManyToManyCallbacks(t *testing.T) {
1664 Level2s []Level2 `gorm:"many2many:level1_level2s;AssociationForeignKey:ID;ForeignKey:ID"`
1668 DB.DropTableIfExists("level1_level2s")
1669 DB.DropTableIfExists(new(Level1))
1670 DB.DropTableIfExists(new(Level2))
1672 if err := DB.AutoMigrate(new(Level1), new(Level2)).Error; err != nil {
1679 Level2{Name: "l2-1"}, Level2{Name: "l2-2"},
1686 DB.Callback().Query().After("gorm:query").Register("TestPreloadManyToManyCallbacks", func(scope *gorm.Scope) {
1690 DB.Preload("Level2s").First(&Level1{}, "id = ?", lvl.ID)
1693 t.Errorf("Wanted callback to be called 3 times but got %d", called)
1697 func toJSONString(v interface{}) []byte {
1698 r, _ := json.MarshalIndent(v, "", " ")