【问题标题】:How to cascade (soft) delete has many relationships in GORM?如何级联(软)删除在 GORM 中有很多关系?
【发布时间】:2021-06-09 20:14:15
【问题描述】:

我正在使用 GORM 实现一些删除功能。我的想法是级联删除,当父行被删除时,子行也被删除。我试过delete with select。但它只会删除父记录。

func DeleteProject(db *gorm.DB, id uint) (Project, error) {
    var project Project
    if err := db.Select(clause.Associations).Delete(&project, id).Error; err != nil {
        return Project{}, err
    }
    return project, nil
}

我有以下型号:

type Project struct {
    ID           uint           `gorm:"primary_key" json:"id"`
    CreatedAt    time.Time      `json:"created_at"`
    UpdatedAt    time.Time      `json:"updated_at"`
    DeletedAt    gorm.DeletedAt `gorm:"index" json:"deleted_at"`
    TicketNumber string         `gorm:"size:6;unique;not null" json:"ticketnumber"`
    Name         string         `json:"name"`
    MailingList  string         `json:"mailinglist"`
    Environment  string         `gorm:"not null" json:"environment"`
    UserID       uint           `gorm:"index" json:"user_id"`
    Diagrams     []Diagram      `json:"diagrams"`
}

type Diagram struct {
    ID        uint           `gorm:"primary_key" json:"id"`
    CreatedAt time.Time      `json:"created_at"`
    UpdatedAt time.Time      `json:"updated_at"`
    DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at"`
    Data      string         `json:"data"`
    ProjectID uint           `gorm:"index" json:"project_id"`
    Instances []Instance     `json:"instances"`
}

type Instance struct {
    ID        uint           `gorm:"primary_key" json:"id"`
    CreatedAt time.Time      `json:"created_at"`
    UpdatedAt time.Time      `json:"updated_at"`
    DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at"`
    Key       uint           `json:"key"`
    DiagramID uint           `gorm:"index" json:"diagram_id"`
}

一个项目可以有多个图表,一个图表可以有多个实例。但是当我运行DeleteProject 函数时,它只会删除Project 而不会删除相关的图表和实例。

在这种情况下,如何删除项目及其关联的图表和实例?

【问题讨论】:

    标签: go go-gorm


    【解决方案1】:

    我找到了一个解决方案,但我认为它不是级联删除的最佳选择,它至少解决了我的问题。我编写了以下代码:

    首先是DeleteProject 函数,我在其中循环所有Diagrams 并调用DeleteDiagram 函数,最后在删除项目之前我还清除了与该项目的所有关联。

    //Delete a project and it's associations.
    func DeleteProject(db *gorm.DB, id uint) (Project, error) {
        project, err := GetProject(db, id)
        if err != nil {
            return Project{}, err
        }
        if len(project.Diagrams) > 0 {
            for _, projectDiagram := range project.Diagrams {
                _, err := DeleteDiagram(db, projectDiagram.ID)
                if err != nil {
                    return Project{}, err
                }
            }
            db.Model(&project).Association("Diagrams").Clear()
        }
        if err := db.Delete(&project, id).Error; err != nil {
            return Project{}, err
        }
        return project, nil
    }
    

    DeleteDiagram 的作用相同,但随后使用 Instances

    //Delete a diagram and it's associations.
    func DeleteDiagram(db *gorm.DB, id uint) (Diagram, error) {
        var diagram, err = GetDiagram(db, id)
        if err != nil {
            return Diagram{}, err
        }
        if len(diagram.Instances) > 0 {
            db.Model(&diagram).Association("Instances").Clear()
            for _, diagramInstance := range diagram.Instances {
                _, err := DeleteInstance(db, diagramInstance.ID)
                if err != nil {
                    return Diagram{}, err
                }
            }
        }
        if err := db.Delete(&diagram).Error; err != nil {
            return Diagram{}, err
        }
        return diagram, nil
    }
    
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-01
      • 2022-11-02
      • 2017-11-17
      相关资源
      最近更新 更多