如何在Golang中使用gorm执行嵌套删除操作?

huangapple go评论80阅读模式
英文:

How can I perform nested deletes gorm Golang?

问题

我有一个名为Customers的表,其中包含Cars,而Cars又有Services。
当我删除Car时,我也希望从数据库中删除Services。
当我删除Customer时,我希望能够删除Customer、它的Cars和它的Services。

我尝试了以下代码来删除Car及其相关的Services,但它只删除了数据库中的Car,如何同时删除Cars和它的Services呢?

type Customer struct {
    gorm.Model

    FirstName string
    LastName  string
    Phone     string `gorm:"type:varchar(100);unique_index"`
    Cars      []Car  `gorm:"constraint:OnDelete:CASCADE;"`
}

type Car struct {
    gorm.Model

    Make       string
    Modelo     string
    Color      string
    VinNumber  string     `gorm:"type:varchar(100);unique_index"`
    Services   []*Service `gorm:"constraint:OnDelete:CASCADE;"`
    CustomerId int
}

type Service struct {
    gorm.Model

    Comment string
    Miles   string
    CarId   int
}

// 删除Customer的端点
func deleteCustomer(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)

    setupResponse(&w, r)
    if (*r).Method == "OPTIONS" {
        return
    }

    var customer Customer
    db.First(&customer, params["id"])
    db.Unscoped().Delete(&customer)

    json.NewEncoder(w).Encode(&customer)
}

// 删除Car的端点
func deleteCar(w http.ResponseWriter, r *http.Request) {
    setupResponse(&w, r)
    if (*r).Method == "OPTIONS" {
        return
    }

    params := mux.Vars(r)

    var car Car
    db.First(&car, params["id"])
    db.Select("Services").Unscoped().Delete(&car)
    json.NewEncoder(w).Encode(&car)
}

我已经尝试了大部分在StackOverflow和文档中看到的方法,但迄今为止似乎没有任何方法能够解决这个问题。

英文:

I have a table Customers with Cars, and Cars has Services.
When I delete the Car I also want to delete the Services from the database
And when I delete the Customer I want to be able to delete Customer, its Cars, Its Services.

I tried the following to delete Car and Services related to the Car, but it only deletes the Car from the database, how do I delete both Cars and its Services?

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

type Customer struct {
gorm.Model
FirstName string
LastName  string
Phone     string `gorm:&quot;typevarchar(100);unique_index&quot;`
Cars      []Car  `gorm:&quot;constraint:OnDelete:CASCADE;&quot;`
}
type Car struct {
gorm.Model
Make       string
Modelo     string
Color      string
VinNumber  string     `gorm:&quot;typevarchar(100);unique_index&quot;`
Services   []*Service `gorm:&quot;constraint:OnDelete:CASCADE;&quot;`
CustomerId int
}
type Service struct {
gorm.Model
Comment string
Miles   string
CarId   int
}
//endpoints
//delete customer
func deleteCustomer(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
setupResponse(&amp;w, r)
if (*r).Method == &quot;OPTIONS&quot; {
return
}
var customer Customer
db.First(&amp;customer, params[&quot;id&quot;])
db.Unscoped().Delete(&amp;customer)
json.NewEncoder(w).Encode(&amp;customer)
}
func deleteCar(w http.ResponseWriter, r *http.Request) {
setupResponse(&amp;w, r)
if (*r).Method == &quot;OPTIONS&quot; {
return
}
params := mux.Vars(r)
var car Car
db.First(&amp;car, params[&quot;id&quot;])
db.Select(&quot;Services&quot;).Unscoped().Delete(&amp;car)
json.NewEncoder(w).Encode(&amp;car)
}

<!-- end snippet -->

I already tried most of what I seen in StackOverflow and the docs but nothing seems to work so far.

答案1

得分: 0

在阅读了文档和一堆StackOverflow答案后,对我来说没有什么真正有效的方法。文档和/或StackOverflow建议我在迁移模型时添加约束,或者在结构体gorm:"constraint:OnDelete:CASCADE;"中添加约束,我还尝试了db.Select("cars").Delete(&customers),但没有成功。这是我处理的方式,不确定是否是最佳实践,但它会从数据库中删除相关记录。
我像这样更新了deleteCustomer和deleteCar端点:

//删除客户
func deleteCustomer(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)

    setupResponse(&w, r)
    if (*r).Method == "OPTIONS" {
        return
    }

    var customer Customer
    var cars []Car

    db.First(&customer, params["id"])
    db.Model(&customer).Related(&cars)

    deleteServicesSqlStatement := `
        DELETE FROM services
        WHERE car_id = $1;`

    for i, car := range cars {
        fmt.Println(i, car.ID)
        err := db.Exec(deleteServicesSqlStatement, car.ID).Error
        if err != nil {
            fmt.Println(err)
        }

    }

    DeleteCarsSqlStatement := `
        DELETE FROM cars
        WHERE customer_id = $1;`

    err := db.Exec(DeleteCarsSqlStatement, params["id"]).Error
    if err != nil {
        fmt.Println(err)
    }

    db.Debug().Unscoped().Delete(&customer)
    json.NewEncoder(w).Encode(&customer)

}


//删除汽车
func deleteCar(w http.ResponseWriter, r *http.Request) {
    //处理CORS
    setupResponse(&w, r)
    if (*r).Method == "OPTIONS" {
        return
    }

    params := mux.Vars(r)

    var car Car
    db.First(&car, params["id"])

    sqlStatement := `
        DELETE FROM services
        WHERE car_id = $1;`

    err := db.Exec(sqlStatement, params["id"]).Error

    if err != nil {
        fmt.Println(err)
    }

    db.Debug().Unscoped().Delete(&car)
    json.NewEncoder(w).Encode(&car)
}

希望对你有帮助!

英文:

After reading the docs and a bunch of StackOverflow answers nothing really worked for me. The docs and/or StackOverflow suggested I add constraints when I migrated the models, or/and add the constraints to the structs gorm:&quot;constraint:OnDelete:CASCADE;&quot;
, I also tried db.Select(&quot;cars&quot;).Delete(&amp;customers) with no success. This is how I went about it, not sure if it's the best practice but it deletes its related records from the database.
I updated the deleteCustomer and deleteCar endpoint like this:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

//delete customer
func deleteCustomer(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
setupResponse(&amp;w, r)
if (*r).Method == &quot;OPTIONS&quot; {
return
}
var customer Customer
var cars []Car
db.First(&amp;customer, params[&quot;id&quot;])
db.Model(&amp;customer).Related(&amp;cars)
deleteServicesSqlStatement := `
DELETE FROM services
WHERE car_id = $1;`
for i, car := range cars {
fmt.Println(i, car.ID)
err := db.Exec(deleteServicesSqlStatement, car.ID).Error
if err != nil {
fmt.Println(err)
}
}
DeleteCarsSqlStatement := `
DELETE FROM cars
WHERE customer_id = $1;`
err := db.Exec(DeleteCarsSqlStatement, params[&quot;id&quot;]).Error
if err != nil {
fmt.Println(err)
}
db.Debug().Unscoped().Delete(&amp;customer)
json.NewEncoder(w).Encode(&amp;customer)
}
//delete car
func deleteCar(w http.ResponseWriter, r *http.Request) {
//handle CORS
setupResponse(&amp;w, r)
if (*r).Method == &quot;OPTIONS&quot; {
return
}
params := mux.Vars(r)
var car Car
db.First(&amp;car, params[&quot;id&quot;])
sqlStatement := `
DELETE FROM services
WHERE car_id = $1;`
err := db.Exec(sqlStatement, params[&quot;id&quot;]).Error
if err != nil {
fmt.Println(err)
}
db.Debug().Unscoped().Delete(&amp;car)
json.NewEncoder(w).Encode(&amp;car)
}

<!-- end snippet -->

huangapple
  • 本文由 发表于 2021年10月21日 23:49:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/69665061.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定