如何设置关联deletedAt字段与软删除



我应该如何使用软删除删除中的关联?

我有以下结构

type PrivateGormModel struct {
ID        uint       `gorm:"primaryKey" json:"id,string"`
CreatedAt time.Time  `json:"-"`
UpdatedAt time.Time  `json:"-"`
DeletedAt *time.Time `gorm:"index" json:"-"`
}
type Relation struct {
PrivateGormModel
OwnerID      uint          `json:"ownerID"`
OwnerType    string        `json:"ownerType"`
Addresses    []Address     `gorm:"polymorphic:Owner;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"addresses"`
Contacts     []Contact     `gorm:"polymorphic:Owner;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"contacts"`
People       []Person      `gorm:"polymorphic:Owner;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"people"`
BankAccounts []BankAccount `gorm:"polymorphic:Owner;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"bankAccounts"`
}
type Company struct {
PrivateGormModel
Name     string   `json:"name"`
Relation Relation `gorm:"polymorphic:Owner;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"relation"`
}

为了简短起见,我省略了地址、联系人、人员和银行账户结构,但它们是带有OwnerIDOwnerType的简单结构。下面的处理程序

func DeleteCompany(db *database.Database) fiber.Handler {
return func(c *fiber.Ctx) error {
id, err := IDFromParams(c)
if err != nil {
return c.JSON(responseKit.ParameterMissing())
}
toDelete := new(model.Company)
result := db.Preload("Relation.Addresses").
Preload("Relation.Contacts").
Preload("Relation.People").
Preload("Relation.BankAccounts").
Preload(clause.Associations).
First(toDelete, id)
fmt.Printf("n%v", toDelete)
result = db.Select("Relation.Addresses").
Select("Relation.Contacts").
Select("Relation.People").
Select("Relation.BankAccounts").
Select("Relation").
Debug().
Delete(toDelete)
if result.Error != nil {
return c.JSON(responseKit.RecordDeleteError())
}
return c.JSON(responseKit.RecordDeleteSuccess())
}
}

打印输出的位置

{PrivateGormModel:{ID:5 CreatedAt:2021-01-15 11:24:03.672857 +0100 CET UpdatedAt:2021-01-15 11:24:03.672857 +0100 CET DeletedAt:<nil>} Name:Test Relation:{PrivateGormModel:{ID:5 CreatedAt:2021-01-15 11:24:03.738351 +0100 CET UpdatedAt:2021-01-15 11:24:03.738351 +0100 CET DeletedAt:<nil>} OwnerID:5 OwnerType:companies Addresses:[{PrivateGormModel:{ID:5 CreatedAt:2021-01-15 11:24:03.739322 +0100 CET UpdatedAt:2021-01-15 11:24:03.739322 +0100 CET DeletedAt:<nil>} OwnerID:5 OwnerType:relations Country:AA Zip:1111AB Number:1 Addition: Street:Test State:Test City:Test}] Contacts:[{PrivateGormModel:{ID:5 CreatedAt:2021-01-15 11:24:03.740319 +0100 CET UpdatedAt:2021-01-15 11:24:03.740319 +0100 CET 
DeletedAt:<nil>} OwnerID:5 OwnerType:relations Tel:0612345678 Mail:test@test.com URL:}] People:[] BankAccounts:[{PrivateGormModel:{ID:5 CreatedAt:2021-01-15 11:24:03.740319 +0100 CET UpdatedAt:2021-01-15 11:24:03.740319 +0100 CET DeletedAt:<nil>} OwnerID:5 OwnerType:relations Bank:test BIC:test IBAN:test AccountHolder: Establishment:test}]}}

并且调试调试以下

DELETE FROM "relations" WHERE "relations"."owner_type" = 'companies' AND "relations"."owner_id" = 5
DELETE FROM "companies" WHERE "companies"."id" = 5

因此,该关系被删除。但这对hasMany关系没有任何帮助。我读过这个

https://gorm.io/docs/associations.html#Delete-选择

我试着这样做,因为限制似乎没有任何作用,但似乎什么都不起作用,并删除了地址、联系人、人员和银行账户。我应该如何软删除公司的所有关系?

我已经用最新版本的Gorm测试了这一点,Select和Delete只适用于一级关联。

所以如果你做

db.Select("Relation").Delete(toDelete)

您会看到Company和Relation都将DeletedAt设置为当前时间戳。

为了实现二级关系的软删除,您需要在单独的调用中删除这些关系:

db.Select("Addresses", "Contacts", "People", "BankAccounts").Delete(toDelete.Relation)
// or more compactly
db.Select(clause.Associations).Delete(toDelete.Relation)

还可能值得问问自己,对于您的用例来说,仅仅软删除模型树的根,并保持其他所有内容不变是否还不够。

最新更新