diff --git a/soft_delete.go b/soft_delete.go index 9b5982b1..417a885f 100644 --- a/soft_delete.go +++ b/soft_delete.go @@ -84,11 +84,12 @@ func (sd SoftDeleteQueryClause) ModifyStatement(stmt *Statement) { } // Modify for Joins[i].ON exprs - if _, ok := stmt.Clauses["soft_delete_join_enabled"]; !ok && !stmt.Statement.Unscoped { - if c, ok := stmt.Clauses["FROM"]; ok && len(stmt.Joins) > 0 { + if c, ok := stmt.Clauses["FROM"]; ok && len(stmt.Joins) > 0 && sd.Field.Schema != nil { + joinedRelationName := "soft_delete_join_enabled" + sd.Field.Schema.Table + if _, ok := stmt.Clauses[joinedRelationName]; !ok && !stmt.Statement.Unscoped { if fromClause, ok := c.Expression.(clause.From); ok && len(fromClause.Joins) > 0 { for i, j := range fromClause.Joins { - if sd.Field.Schema != nil && j.Table.Name == sd.Field.Schema.Table { + if j.Table.Name == sd.Field.Schema.Table { j.ON.Exprs = append(j.ON.Exprs, clause.Eq{ Column: clause.Column{Table: j.Table.Alias, Name: sd.Field.DBName}, Value: nil, }) @@ -97,7 +98,7 @@ func (sd SoftDeleteQueryClause) ModifyStatement(stmt *Statement) { } } stmt.Clauses["FROM"] = c - stmt.Clauses["soft_delete_join_enabled"] = clause.Clause{} + stmt.Clauses[joinedRelationName] = clause.Clause{} } } } diff --git a/tests/helper_test.go b/tests/helper_test.go index eee34e99..7ee2a576 100644 --- a/tests/helper_test.go +++ b/tests/helper_test.go @@ -19,6 +19,7 @@ type Config struct { Team int Languages int Friends int + NamedPet bool } func GetUser(name string, config Config) *User { @@ -65,6 +66,10 @@ func GetUser(name string, config Config) *User { user.Friends = append(user.Friends, GetUser(name+"_friend_"+strconv.Itoa(i+1), Config{})) } + if config.NamedPet { + user.NamedPet = &Pet{Name: name + "_namepet"} + } + return &user } diff --git a/tests/joins_test.go b/tests/joins_test.go index 928da627..f1bf907f 100644 --- a/tests/joins_test.go +++ b/tests/joins_test.go @@ -203,21 +203,32 @@ func TestJoinCount(t *testing.T) { // https://github.com/go-gorm/gorm/issues/4918 func TestJoinWithSoftDeleted(t *testing.T) { - user := User{Name: "TestJoinWithSoftDeleted"} + DB = DB.Debug() + + user := GetUser("TestJoinWithSoftDeletedUser", Config{Account: true, NamedPet: true}) DB.Create(&user) - pet := Pet{Name: "A", UserID: &user.ID} - DB.Create(&pet) - var user1 User - DB.Model(&User{}).Joins("NamedPet").First(&user1, user.ID) - AssertEqual(t, user1.ID, user.ID) - AssertEqual(t, user1.NamedPet.ID, pet.ID) + DB.Model(&User{}).Joins("NamedPet").Joins("Account").First(&user1, user.ID) + if user1.NamedPet == nil || user1.Account.ID == 0 { + t.Fatalf("joins NamedPet and Account should not empty:%v", user1) + } - DB.Delete(&pet) + // Account should empty + DB.Delete(&user1.Account) + + var user2 User + DB.Model(&User{}).Joins("NamedPet").Joins("Account").First(&user2, user.ID) + if user2.NamedPet == nil || user2.Account.ID != 0 { + t.Fatalf("joins Account should not empty:%v", user2) + } + + // NamedPet should empty + DB.Delete(&user1.NamedPet) var user3 User - DB.Model(&User{}).Joins("NamedPet").First(&user3, user.ID) - AssertEqual(t, user3.ID, user.ID) - AssertEqual(t, user3.NamedPet, nil) // soft deleted for join.on + DB.Model(&User{}).Joins("NamedPet").Joins("Account").First(&user3, user.ID) + if user3.NamedPet != nil || user2.Account.ID != 0 { + t.Fatalf("joins NamedPet and Account should not empty:%v", user2) + } }