diff --git a/callbacks/query.go b/callbacks/query.go index 97fe8a49..9a6d4f4a 100644 --- a/callbacks/query.go +++ b/callbacks/query.go @@ -257,6 +257,7 @@ func Preload(db *gorm.DB) { return } preloadDB.Statement.ReflectValue = db.Statement.ReflectValue + preloadDB.Statement.Unscoped = db.Statement.Unscoped for _, name := range preloadNames { if rel := preloadDB.Statement.Schema.Relationships.Relations[name]; rel != nil { diff --git a/tests/helper_test.go b/tests/helper_test.go index d40fa5ce..d0cda051 100644 --- a/tests/helper_test.go +++ b/tests/helper_test.go @@ -1,6 +1,7 @@ package tests_test import ( + "gorm.io/gorm" "os" "sort" "strconv" @@ -74,10 +75,18 @@ func GetUser(name string, config Config) *User { return &user } +func CheckPetUnscoped(t *testing.T, pet Pet, expect Pet) { + doCheckPet(t, pet, expect, true) +} + func CheckPet(t *testing.T, pet Pet, expect Pet) { + doCheckPet(t, pet, expect, false) +} + +func doCheckPet(t *testing.T, pet Pet, expect Pet, unscoped bool) { if pet.ID != 0 { var newPet Pet - if err := DB.Where("id = ?", pet.ID).First(&newPet).Error; err != nil { + if err := db(unscoped).Where("id = ?", pet.ID).First(&newPet).Error; err != nil { t.Fatalf("errors happened when query: %v", err) } else { AssertObjEqual(t, newPet, pet, "ID", "CreatedAt", "UpdatedAt", "DeletedAt", "UserID", "Name") @@ -94,10 +103,18 @@ func CheckPet(t *testing.T, pet Pet, expect Pet) { } } +func CheckUserUnscoped(t *testing.T, user User, expect User) { + doCheckUser(t, user, expect, true) +} + func CheckUser(t *testing.T, user User, expect User) { + doCheckUser(t, user, expect, false) +} + +func doCheckUser(t *testing.T, user User, expect User, unscoped bool) { if user.ID != 0 { var newUser User - if err := DB.Where("id = ?", user.ID).First(&newUser).Error; err != nil { + if err := db(unscoped).Where("id = ?", user.ID).First(&newUser).Error; err != nil { t.Fatalf("errors happened when query: %v", err) } else { AssertObjEqual(t, newUser, user, "ID", "CreatedAt", "UpdatedAt", "DeletedAt", "Name", "Age", "Birthday", "CompanyID", "ManagerID", "Active") @@ -114,7 +131,7 @@ func CheckUser(t *testing.T, user User, expect User) { t.Errorf("Account's foreign key should be saved") } else { var account Account - DB.First(&account, "user_id = ?", user.ID) + db(unscoped).First(&account, "user_id = ?", user.ID) AssertObjEqual(t, account, user.Account, "ID", "CreatedAt", "UpdatedAt", "DeletedAt", "UserID", "Number") } } @@ -137,7 +154,7 @@ func CheckUser(t *testing.T, user User, expect User) { if pet == nil || expect.Pets[idx] == nil { t.Errorf("pets#%v should equal, expect: %v, got %v", idx, expect.Pets[idx], pet) } else { - CheckPet(t, *pet, *expect.Pets[idx]) + doCheckPet(t, *pet, *expect.Pets[idx], unscoped) } } }) @@ -174,7 +191,7 @@ func CheckUser(t *testing.T, user User, expect User) { t.Errorf("Manager's foreign key should be saved") } else { var manager User - DB.First(&manager, "id = ?", *user.ManagerID) + db(unscoped).First(&manager, "id = ?", *user.ManagerID) AssertObjEqual(t, manager, user.Manager, "ID", "CreatedAt", "UpdatedAt", "DeletedAt", "Name", "Age", "Birthday", "CompanyID", "ManagerID", "Active") AssertObjEqual(t, manager, expect.Manager, "ID", "CreatedAt", "UpdatedAt", "DeletedAt", "Name", "Age", "Birthday", "CompanyID", "ManagerID", "Active") } @@ -246,3 +263,11 @@ func tidbSkip(t *testing.T, reason string) { func isTiDB() bool { return os.Getenv("GORM_DIALECT") == "tidb" } + +func db(unscoped bool) *gorm.DB { + if unscoped { + return DB.Unscoped() + } else { + return DB + } +} diff --git a/tests/preload_test.go b/tests/preload_test.go index cb4343ec..e7223b3e 100644 --- a/tests/preload_test.go +++ b/tests/preload_test.go @@ -269,3 +269,40 @@ func TestPreloadWithDiffModel(t *testing.T) { CheckUser(t, user, result.User) } + +func TestNestedPreloadWithUnscoped(t *testing.T) { + user := *GetUser("nested_preload", Config{Pets: 1}) + pet := user.Pets[0] + pet.Toy = Toy{Name: "toy_nested_preload_" + strconv.Itoa(1)} + pet.Toy = Toy{Name: "toy_nested_preload_" + strconv.Itoa(2)} + + if err := DB.Create(&user).Error; err != nil { + t.Fatalf("errors happened when create: %v", err) + } + + var user2 User + DB.Preload("Pets.Toy").Find(&user2, "id = ?", user.ID) + CheckUser(t, user2, user) + + DB.Delete(&pet) + + var user3 User + DB.Preload(clause.Associations+"."+clause.Associations).Find(&user3, "id = ?", user.ID) + if len(user3.Pets) != 0 { + t.Fatalf("User.Pet[0] was deleted and should not exist.") + } + + var user4 *User + DB.Preload("Pets.Toy").Find(&user4, "id = ?", user.ID) + if len(user4.Pets) != 0 { + t.Fatalf("User.Pet[0] was deleted and should not exist.") + } + + var user5 User + DB.Unscoped().Preload(clause.Associations+"."+clause.Associations).Find(&user5, "id = ?", user.ID) + CheckUserUnscoped(t, user5, user) + + var user6 *User + DB.Unscoped().Preload("Pets.Toy").Find(&user6, "id = ?", user.ID) + CheckUserUnscoped(t, *user6, user) +}