fix: should add deleted_at exprs for every joins

This commit is contained in:
chenrui 2022-03-07 20:33:12 +08:00
parent 2b7a1bdcf3
commit 8559f51102
3 changed files with 32 additions and 15 deletions

View File

@ -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{}
}
}
}

View File

@ -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
}

View File

@ -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)
}
}