Test Preload for BelongsTo/HasOne/HasMany
This commit is contained in:
		
							parent
							
								
									b549f9bb9a
								
							
						
					
					
						commit
						42aae57240
					
				| @ -85,27 +85,31 @@ func getIdentityFieldValuesMap(reflectValue reflect.Value, fields []*schema.Fiel | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func preloadData(tx *gorm.DB, resultSchema *schema.Schema, foreignKeys []string, foreignValues [][]interface{}) reflect.Value { | func preloadData(tx *gorm.DB, resultSchema *schema.Schema, foreignKeys []string, foreignValues [][]interface{}) reflect.Value { | ||||||
| 	results := reflect.MakeSlice(reflect.SliceOf(resultSchema.ModelType), 0, 0) | 	slice := reflect.MakeSlice(reflect.SliceOf(resultSchema.ModelType), 0, 0) | ||||||
|  | 	results := reflect.New(slice.Type()) | ||||||
|  | 	results.Elem().Set(slice) | ||||||
|  | 
 | ||||||
| 	queryValues := make([]interface{}, len(foreignValues)) | 	queryValues := make([]interface{}, len(foreignValues)) | ||||||
| 	if len(foreignKeys) == 1 { | 	if len(foreignKeys) == 1 { | ||||||
| 		for idx, r := range foreignValues { | 		for idx, r := range foreignValues { | ||||||
| 			queryValues[idx] = r[0] | 			queryValues[idx] = r[0] | ||||||
| 		} | 		} | ||||||
| 		tx.Where(clause.IN{Column: foreignKeys[0], Values: queryValues}).Find(results.Addr().Interface()) | 		tx.Where(clause.IN{Column: foreignKeys[0], Values: queryValues}).Find(results.Interface()) | ||||||
| 	} else { | 	} else { | ||||||
| 		for idx, r := range foreignValues { | 		for idx, r := range foreignValues { | ||||||
| 			queryValues[idx] = r | 			queryValues[idx] = r | ||||||
| 		} | 		} | ||||||
| 		tx.Where(clause.IN{Column: foreignKeys, Values: queryValues}).Find(results.Addr().Interface()) | 		tx.Where(clause.IN{Column: foreignKeys, Values: queryValues}).Find(results.Interface()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return results | 	return results.Elem() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func preload(tx *gorm.DB, rels []*schema.Relationship, conds []interface{}) { | func preload(db *gorm.DB, rels []*schema.Relationship, conds []interface{}) { | ||||||
| 	var ( | 	var ( | ||||||
| 		reflectValue     = tx.Statement.ReflectValue | 		reflectValue     = db.Statement.ReflectValue | ||||||
| 		rel              = rels[len(rels)-1] | 		rel              = rels[len(rels)-1] | ||||||
|  | 		tx               = db.Session(&gorm.Session{}) | ||||||
| 		relForeignKeys   []string | 		relForeignKeys   []string | ||||||
| 		relForeignFields []*schema.Field | 		relForeignFields []*schema.Field | ||||||
| 		foreignFields    []*schema.Field | 		foreignFields    []*schema.Field | ||||||
| @ -177,7 +181,7 @@ func preload(tx *gorm.DB, rels []*schema.Relationship, conds []interface{}) { | |||||||
| 
 | 
 | ||||||
| 	fieldValues := make([]reflect.Value, len(foreignFields)) | 	fieldValues := make([]reflect.Value, len(foreignFields)) | ||||||
| 	for i := 0; i < reflectResults.Len(); i++ { | 	for i := 0; i < reflectResults.Len(); i++ { | ||||||
| 		for idx, field := range foreignFields { | 		for idx, field := range relForeignFields { | ||||||
| 			fieldValues[idx] = field.ReflectValueOf(reflectResults.Index(i)) | 			fieldValues[idx] = field.ReflectValueOf(reflectResults.Index(i)) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @ -185,11 +189,13 @@ func preload(tx *gorm.DB, rels []*schema.Relationship, conds []interface{}) { | |||||||
| 			reflectFieldValue := reflect.Indirect(rel.Field.ReflectValueOf(data)) | 			reflectFieldValue := reflect.Indirect(rel.Field.ReflectValueOf(data)) | ||||||
| 			switch reflectFieldValue.Kind() { | 			switch reflectFieldValue.Kind() { | ||||||
| 			case reflect.Struct: | 			case reflect.Struct: | ||||||
| 				elem := reflectResults.Index(i).Convert(reflectFieldValue.Type().Elem()) | 				rel.Field.Set(data, reflectResults.Index(i).Interface()) | ||||||
| 				rel.Field.Set(data, elem.Interface()) |  | ||||||
| 			case reflect.Slice, reflect.Array: | 			case reflect.Slice, reflect.Array: | ||||||
| 				elem := reflectResults.Index(i).Convert(reflectFieldValue.Type().Elem()) | 				if reflectFieldValue.Type().Elem().Kind() == reflect.Ptr { | ||||||
| 				rel.Field.Set(data, reflect.Append(reflectFieldValue, elem).Interface()) | 					rel.Field.Set(data, reflect.Append(reflectFieldValue, reflectResults.Index(i).Addr()).Interface()) | ||||||
|  | 				} else { | ||||||
|  | 					rel.Field.Set(data, reflect.Append(reflectFieldValue, reflectResults.Index(i)).Interface()) | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -133,7 +133,7 @@ func Preload(db *gorm.DB) { | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			preload(db.Session(&gorm.Session{}), rels, db.Statement.Preloads[name]) | 			preload(db, rels, db.Statement.Preloads[name]) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										138
									
								
								tests/create.go
									
									
									
									
									
								
							
							
						
						
									
										138
									
								
								tests/create.go
									
									
									
									
									
								
							| @ -56,14 +56,16 @@ func TestCreateAssociations(t *testing.T, db *gorm.DB) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestCreateBelongsToAssociations(t *testing.T, db *gorm.DB) { | func TestCreateBelongsToAssociations(t *testing.T, db *gorm.DB) { | ||||||
| 	check := func(t *testing.T, user User) { | 	check := func(t *testing.T, user User, old User) { | ||||||
| 		if user.Company.Name != "" { | 		if old.Company.Name != "" { | ||||||
| 			if user.CompanyID == nil { | 			if user.CompanyID == nil { | ||||||
| 				t.Errorf("Company's foreign key should be saved") | 				t.Errorf("Company's foreign key should be saved") | ||||||
| 			} else { | 			} else { | ||||||
| 				var company Company | 				var company Company | ||||||
| 				db.First(&company, "id = ?", *user.CompanyID) | 				db.First(&company, "id = ?", *user.CompanyID) | ||||||
| 				if company.Name != user.Company.Name { | 				if company.Name != old.Company.Name { | ||||||
|  | 					t.Errorf("Company's name should be same") | ||||||
|  | 				} else if user.Company.Name != old.Company.Name { | ||||||
| 					t.Errorf("Company's name should be same") | 					t.Errorf("Company's name should be same") | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| @ -71,7 +73,7 @@ func TestCreateBelongsToAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 			t.Errorf("Company should not be created for zero value, got: %+v", user.CompanyID) | 			t.Errorf("Company should not be created for zero value, got: %+v", user.CompanyID) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if user.Manager != nil { | 		if old.Manager != nil { | ||||||
| 			if user.ManagerID == nil { | 			if user.ManagerID == nil { | ||||||
| 				t.Errorf("Manager's foreign key should be saved") | 				t.Errorf("Manager's foreign key should be saved") | ||||||
| 			} else { | 			} else { | ||||||
| @ -79,6 +81,8 @@ func TestCreateBelongsToAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 				db.First(&manager, "id = ?", *user.ManagerID) | 				db.First(&manager, "id = ?", *user.ManagerID) | ||||||
| 				if manager.Name != user.Manager.Name { | 				if manager.Name != user.Manager.Name { | ||||||
| 					t.Errorf("Manager's name should be same") | 					t.Errorf("Manager's name should be same") | ||||||
|  | 				} else if user.Manager.Name != old.Manager.Name { | ||||||
|  | 					t.Errorf("Manager's name should be same") | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} else if user.ManagerID != nil { | 		} else if user.ManagerID != nil { | ||||||
| @ -99,7 +103,11 @@ func TestCreateBelongsToAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 			t.Fatalf("errors happened when create: %v", err) | 			t.Fatalf("errors happened when create: %v", err) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		check(t, user) | 		check(t, user, user) | ||||||
|  | 
 | ||||||
|  | 		var user2 User | ||||||
|  | 		db.Preload("Company").Preload("Manager").Find(&user2, "id = ?", user.ID) | ||||||
|  | 		check(t, user2, user) | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	t.Run("BelongsToForBulkInsert", func(t *testing.T) { | 	t.Run("BelongsToForBulkInsert", func(t *testing.T) { | ||||||
| @ -126,8 +134,22 @@ func TestCreateBelongsToAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 			t.Fatalf("errors happened when create: %v", err) | 			t.Fatalf("errors happened when create: %v", err) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		var userIDs []uint | ||||||
| 		for _, user := range users { | 		for _, user := range users { | ||||||
| 			check(t, user) | 			userIDs = append(userIDs, user.ID) | ||||||
|  | 			check(t, user, user) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		var users2 []User | ||||||
|  | 		db.Preload("Company").Preload("Manager").Find(&users2, "id IN (?)", userIDs) | ||||||
|  | 		for idx, user := range users2 { | ||||||
|  | 			check(t, user, users[idx]) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		var users3 []User | ||||||
|  | 		db.Preload("Company").Preload("Manager").Find(users3, "id IN (?)", userIDs) | ||||||
|  | 		for idx, user := range users3 { | ||||||
|  | 			check(t, user, users[idx]) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| @ -156,7 +178,7 @@ func TestCreateBelongsToAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for _, user := range users { | 		for _, user := range users { | ||||||
| 			check(t, *user) | 			check(t, *user, *user) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| @ -185,13 +207,13 @@ func TestCreateBelongsToAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for _, user := range users { | 		for _, user := range users { | ||||||
| 			check(t, *user) | 			check(t, *user, *user) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestCreateHasOneAssociations(t *testing.T, db *gorm.DB) { | func TestCreateHasOneAssociations(t *testing.T, db *gorm.DB) { | ||||||
| 	check := func(t *testing.T, user User) { | 	check := func(t *testing.T, user User, old User) { | ||||||
| 		if user.Account.ID == 0 { | 		if user.Account.ID == 0 { | ||||||
| 			t.Errorf("Account should be saved") | 			t.Errorf("Account should be saved") | ||||||
| 		} else if user.Account.UserID.Int64 != int64(user.ID) { | 		} else if user.Account.UserID.Int64 != int64(user.ID) { | ||||||
| @ -200,7 +222,9 @@ func TestCreateHasOneAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 			var account Account | 			var account Account | ||||||
| 			db.First(&account, "id = ?", user.Account.ID) | 			db.First(&account, "id = ?", user.Account.ID) | ||||||
| 			if account.Number != user.Account.Number { | 			if account.Number != user.Account.Number { | ||||||
| 				t.Errorf("Account's number should be sme") | 				t.Errorf("Account's number should be same") | ||||||
|  | 			} else if user.Account.Number != old.Account.Number { | ||||||
|  | 				t.Errorf("Account's number should be same") | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @ -217,7 +241,11 @@ func TestCreateHasOneAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 			t.Fatalf("errors happened when create: %v", err) | 			t.Fatalf("errors happened when create: %v", err) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		check(t, user) | 		check(t, user, user) | ||||||
|  | 
 | ||||||
|  | 		var user2 User | ||||||
|  | 		db.Preload("Account").Find(&user2, "id = ?", user.ID) | ||||||
|  | 		check(t, user2, user) | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	t.Run("HasOneForBulkInsert", func(t *testing.T) { | 	t.Run("HasOneForBulkInsert", func(t *testing.T) { | ||||||
| @ -242,8 +270,16 @@ func TestCreateHasOneAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 			t.Fatalf("errors happened when create: %v", err) | 			t.Fatalf("errors happened when create: %v", err) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		var userIDs []uint | ||||||
| 		for _, user := range users { | 		for _, user := range users { | ||||||
| 			check(t, user) | 			userIDs = append(userIDs, user.ID) | ||||||
|  | 			check(t, user, user) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		var users2 []User | ||||||
|  | 		db.Preload("Account").Find(&users2, "id IN (?)", userIDs) | ||||||
|  | 		for idx, user := range users2 { | ||||||
|  | 			check(t, user, users[idx]) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| @ -270,7 +306,7 @@ func TestCreateHasOneAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for _, user := range users { | 		for _, user := range users { | ||||||
| 			check(t, *user) | 			check(t, *user, *user) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| @ -297,11 +333,11 @@ func TestCreateHasOneAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for _, user := range users { | 		for _, user := range users { | ||||||
| 			check(t, user) | 			check(t, user, user) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	checkPet := func(t *testing.T, pet Pet) { | 	checkPet := func(t *testing.T, pet Pet, old Pet) { | ||||||
| 		if pet.Toy.OwnerID != fmt.Sprint(pet.ID) || pet.Toy.OwnerType != "pets" { | 		if pet.Toy.OwnerID != fmt.Sprint(pet.ID) || pet.Toy.OwnerType != "pets" { | ||||||
| 			t.Errorf("Failed to create polymorphic has one association - toy owner id %v, owner type %v", pet.Toy.OwnerID, pet.Toy.OwnerType) | 			t.Errorf("Failed to create polymorphic has one association - toy owner id %v, owner type %v", pet.Toy.OwnerID, pet.Toy.OwnerType) | ||||||
| 		} else { | 		} else { | ||||||
| @ -309,6 +345,8 @@ func TestCreateHasOneAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 			db.First(&toy, "owner_id = ? and owner_type = ?", pet.Toy.OwnerID, pet.Toy.OwnerType) | 			db.First(&toy, "owner_id = ? and owner_type = ?", pet.Toy.OwnerID, pet.Toy.OwnerType) | ||||||
| 			if toy.Name != pet.Toy.Name { | 			if toy.Name != pet.Toy.Name { | ||||||
| 				t.Errorf("Failed to query saved polymorphic has one association") | 				t.Errorf("Failed to query saved polymorphic has one association") | ||||||
|  | 			} else if old.Toy.Name != pet.Toy.Name { | ||||||
|  | 				t.Errorf("Failed to query saved polymorphic has one association") | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @ -323,7 +361,11 @@ func TestCreateHasOneAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 			t.Fatalf("errors happened when create: %v", err) | 			t.Fatalf("errors happened when create: %v", err) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		checkPet(t, pet) | 		checkPet(t, pet, pet) | ||||||
|  | 
 | ||||||
|  | 		var pet2 Pet | ||||||
|  | 		db.Preload("Toy").Find(&pet2, "id = ?", pet.ID) | ||||||
|  | 		checkPet(t, pet2, pet) | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	t.Run("PolymorphicHasOneForBulkInsert", func(t *testing.T) { | 	t.Run("PolymorphicHasOneForBulkInsert", func(t *testing.T) { | ||||||
| @ -342,8 +384,16 @@ func TestCreateHasOneAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 			t.Fatalf("errors happened when create: %v", err) | 			t.Fatalf("errors happened when create: %v", err) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		var petIDs []uint | ||||||
| 		for _, pet := range pets { | 		for _, pet := range pets { | ||||||
| 			checkPet(t, pet) | 			petIDs = append(petIDs, pet.ID) | ||||||
|  | 			checkPet(t, pet, pet) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		var pets2 []Pet | ||||||
|  | 		db.Preload("Toy").Find(&pets2, "id IN (?)", petIDs) | ||||||
|  | 		for idx, pet := range pets2 { | ||||||
|  | 			checkPet(t, pet, pets[idx]) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| @ -364,7 +414,7 @@ func TestCreateHasOneAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for _, pet := range pets { | 		for _, pet := range pets { | ||||||
| 			checkPet(t, *pet) | 			checkPet(t, *pet, *pet) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| @ -385,14 +435,14 @@ func TestCreateHasOneAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for _, pet := range pets { | 		for _, pet := range pets { | ||||||
| 			checkPet(t, *pet) | 			checkPet(t, *pet, *pet) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestCreateHasManyAssociations(t *testing.T, db *gorm.DB) { | func TestCreateHasManyAssociations(t *testing.T, db *gorm.DB) { | ||||||
| 	check := func(t *testing.T, user User) { | 	check := func(t *testing.T, user User, old User) { | ||||||
| 		for _, pet := range user.Pets { | 		for idx, pet := range user.Pets { | ||||||
| 			if pet.ID == 0 { | 			if pet.ID == 0 { | ||||||
| 				t.Errorf("Pet's foreign key should be saved") | 				t.Errorf("Pet's foreign key should be saved") | ||||||
| 			} | 			} | ||||||
| @ -403,6 +453,8 @@ func TestCreateHasManyAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 				t.Errorf("Pet's name should be same") | 				t.Errorf("Pet's name should be same") | ||||||
| 			} else if result.UserID != user.ID { | 			} else if result.UserID != user.ID { | ||||||
| 				t.Errorf("Pet's foreign key should be saved") | 				t.Errorf("Pet's foreign key should be saved") | ||||||
|  | 			} else if result.Name != old.Pets[idx].Name { | ||||||
|  | 				t.Errorf("Pet's name should be same") | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @ -419,7 +471,11 @@ func TestCreateHasManyAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 			t.Fatalf("errors happened when create: %v", err) | 			t.Fatalf("errors happened when create: %v", err) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		check(t, user) | 		check(t, user, user) | ||||||
|  | 
 | ||||||
|  | 		var user2 User | ||||||
|  | 		db.Preload("Pets").Find(&user2, "id = ?", user.ID) | ||||||
|  | 		check(t, user2, user) | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	t.Run("HasManyForBulkInsert", func(t *testing.T) { | 	t.Run("HasManyForBulkInsert", func(t *testing.T) { | ||||||
| @ -444,8 +500,16 @@ func TestCreateHasManyAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 			t.Fatalf("errors happened when create: %v", err) | 			t.Fatalf("errors happened when create: %v", err) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		var userIDs []uint | ||||||
| 		for _, user := range users { | 		for _, user := range users { | ||||||
| 			check(t, user) | 			userIDs = append(userIDs, user.ID) | ||||||
|  | 			check(t, user, user) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		var users2 []User | ||||||
|  | 		db.Preload("Pets").Find(&users2, "id IN (?)", userIDs) | ||||||
|  | 		for idx, user := range users2 { | ||||||
|  | 			check(t, user, users[idx]) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| @ -472,7 +536,7 @@ func TestCreateHasManyAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for _, user := range users { | 		for _, user := range users { | ||||||
| 			check(t, *user) | 			check(t, *user, *user) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| @ -499,11 +563,11 @@ func TestCreateHasManyAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for _, user := range users { | 		for _, user := range users { | ||||||
| 			check(t, *user) | 			check(t, *user, *user) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	checkToy := func(t *testing.T, user User) { | 	checkToy := func(t *testing.T, user User, old User) { | ||||||
| 		for idx, toy := range user.Toys { | 		for idx, toy := range user.Toys { | ||||||
| 			if toy.ID == 0 { | 			if toy.ID == 0 { | ||||||
| 				t.Fatalf("Failed to create toy #%v", idx) | 				t.Fatalf("Failed to create toy #%v", idx) | ||||||
| @ -513,6 +577,8 @@ func TestCreateHasManyAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 			db.First(&result, "id = ?", toy.ID) | 			db.First(&result, "id = ?", toy.ID) | ||||||
| 			if result.Name != toy.Name { | 			if result.Name != toy.Name { | ||||||
| 				t.Errorf("Failed to query saved toy") | 				t.Errorf("Failed to query saved toy") | ||||||
|  | 			} else if result.Name != old.Toys[idx].Name { | ||||||
|  | 				t.Errorf("Failed to query saved toy") | ||||||
| 			} else if result.OwnerID != fmt.Sprint(user.ID) || result.OwnerType != "users" { | 			} else if result.OwnerID != fmt.Sprint(user.ID) || result.OwnerType != "users" { | ||||||
| 				t.Errorf("Failed to save relation") | 				t.Errorf("Failed to save relation") | ||||||
| 			} | 			} | ||||||
| @ -531,7 +597,11 @@ func TestCreateHasManyAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 			t.Fatalf("errors happened when create: %v", err) | 			t.Fatalf("errors happened when create: %v", err) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		checkToy(t, user) | 		checkToy(t, user, user) | ||||||
|  | 
 | ||||||
|  | 		var user2 User | ||||||
|  | 		db.Preload("Toys").Find(&user2, "id = ?", user.ID) | ||||||
|  | 		check(t, user2, user) | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	t.Run("PolymorphicHasManyForBulkInsert", func(t *testing.T) { | 	t.Run("PolymorphicHasManyForBulkInsert", func(t *testing.T) { | ||||||
| @ -556,8 +626,16 @@ func TestCreateHasManyAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 			t.Fatalf("errors happened when create: %v", err) | 			t.Fatalf("errors happened when create: %v", err) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		var userIDs []uint | ||||||
| 		for _, user := range users { | 		for _, user := range users { | ||||||
| 			checkToy(t, user) | 			userIDs = append(userIDs, user.ID) | ||||||
|  | 			checkToy(t, user, user) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		var users2 []User | ||||||
|  | 		db.Preload("Toys").Find(&users2, "id IN (?)", userIDs) | ||||||
|  | 		for idx, user := range users2 { | ||||||
|  | 			check(t, user, users[idx]) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| @ -584,7 +662,7 @@ func TestCreateHasManyAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for _, user := range users { | 		for _, user := range users { | ||||||
| 			checkToy(t, *user) | 			checkToy(t, *user, *user) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| @ -611,7 +689,7 @@ func TestCreateHasManyAssociations(t *testing.T, db *gorm.DB) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for _, user := range users { | 		for _, user := range users { | ||||||
| 			checkToy(t, user) | 			checkToy(t, user, user) | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package utils | package utils | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"database/sql/driver" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| @ -45,6 +46,9 @@ func ToStringKey(values ...reflect.Value) string { | |||||||
| 
 | 
 | ||||||
| 	for idx, value := range values { | 	for idx, value := range values { | ||||||
| 		rv := reflect.Indirect(value).Interface() | 		rv := reflect.Indirect(value).Interface() | ||||||
|  | 		if valuer, ok := rv.(driver.Valuer); ok { | ||||||
|  | 			rv, _ = valuer.Value() | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		switch v := rv.(type) { | 		switch v := rv.(type) { | ||||||
| 		case string: | 		case string: | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jinzhu
						Jinzhu