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

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

How can I perform nested deletes gorm Golang?

问题

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

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

  1. type Customer struct {
  2. gorm.Model
  3. FirstName string
  4. LastName string
  5. Phone string `gorm:"type:varchar(100);unique_index"`
  6. Cars []Car `gorm:"constraint:OnDelete:CASCADE;"`
  7. }
  8. type Car struct {
  9. gorm.Model
  10. Make string
  11. Modelo string
  12. Color string
  13. VinNumber string `gorm:"type:varchar(100);unique_index"`
  14. Services []*Service `gorm:"constraint:OnDelete:CASCADE;"`
  15. CustomerId int
  16. }
  17. type Service struct {
  18. gorm.Model
  19. Comment string
  20. Miles string
  21. CarId int
  22. }
  23. // 删除Customer的端点
  24. func deleteCustomer(w http.ResponseWriter, r *http.Request) {
  25. params := mux.Vars(r)
  26. setupResponse(&w, r)
  27. if (*r).Method == "OPTIONS" {
  28. return
  29. }
  30. var customer Customer
  31. db.First(&customer, params["id"])
  32. db.Unscoped().Delete(&customer)
  33. json.NewEncoder(w).Encode(&customer)
  34. }
  35. // 删除Car的端点
  36. func deleteCar(w http.ResponseWriter, r *http.Request) {
  37. setupResponse(&w, r)
  38. if (*r).Method == "OPTIONS" {
  39. return
  40. }
  41. params := mux.Vars(r)
  42. var car Car
  43. db.First(&car, params["id"])
  44. db.Select("Services").Unscoped().Delete(&car)
  45. json.NewEncoder(w).Encode(&car)
  46. }

我已经尝试了大部分在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 -->

  1. type Customer struct {
  2. gorm.Model
  3. FirstName string
  4. LastName string
  5. Phone string `gorm:&quot;typevarchar(100);unique_index&quot;`
  6. Cars []Car `gorm:&quot;constraint:OnDelete:CASCADE;&quot;`
  7. }
  8. type Car struct {
  9. gorm.Model
  10. Make string
  11. Modelo string
  12. Color string
  13. VinNumber string `gorm:&quot;typevarchar(100);unique_index&quot;`
  14. Services []*Service `gorm:&quot;constraint:OnDelete:CASCADE;&quot;`
  15. CustomerId int
  16. }
  17. type Service struct {
  18. gorm.Model
  19. Comment string
  20. Miles string
  21. CarId int
  22. }
  23. //endpoints
  24. //delete customer
  25. func deleteCustomer(w http.ResponseWriter, r *http.Request) {
  26. params := mux.Vars(r)
  27. setupResponse(&amp;w, r)
  28. if (*r).Method == &quot;OPTIONS&quot; {
  29. return
  30. }
  31. var customer Customer
  32. db.First(&amp;customer, params[&quot;id&quot;])
  33. db.Unscoped().Delete(&amp;customer)
  34. json.NewEncoder(w).Encode(&amp;customer)
  35. }
  36. func deleteCar(w http.ResponseWriter, r *http.Request) {
  37. setupResponse(&amp;w, r)
  38. if (*r).Method == &quot;OPTIONS&quot; {
  39. return
  40. }
  41. params := mux.Vars(r)
  42. var car Car
  43. db.First(&amp;car, params[&quot;id&quot;])
  44. db.Select(&quot;Services&quot;).Unscoped().Delete(&amp;car)
  45. json.NewEncoder(w).Encode(&amp;car)
  46. }

<!-- 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端点:

  1. //删除客户
  2. func deleteCustomer(w http.ResponseWriter, r *http.Request) {
  3. params := mux.Vars(r)
  4. setupResponse(&w, r)
  5. if (*r).Method == "OPTIONS" {
  6. return
  7. }
  8. var customer Customer
  9. var cars []Car
  10. db.First(&customer, params["id"])
  11. db.Model(&customer).Related(&cars)
  12. deleteServicesSqlStatement := `
  13. DELETE FROM services
  14. WHERE car_id = $1;`
  15. for i, car := range cars {
  16. fmt.Println(i, car.ID)
  17. err := db.Exec(deleteServicesSqlStatement, car.ID).Error
  18. if err != nil {
  19. fmt.Println(err)
  20. }
  21. }
  22. DeleteCarsSqlStatement := `
  23. DELETE FROM cars
  24. WHERE customer_id = $1;`
  25. err := db.Exec(DeleteCarsSqlStatement, params["id"]).Error
  26. if err != nil {
  27. fmt.Println(err)
  28. }
  29. db.Debug().Unscoped().Delete(&customer)
  30. json.NewEncoder(w).Encode(&customer)
  31. }
  32. //删除汽车
  33. func deleteCar(w http.ResponseWriter, r *http.Request) {
  34. //处理CORS
  35. setupResponse(&w, r)
  36. if (*r).Method == "OPTIONS" {
  37. return
  38. }
  39. params := mux.Vars(r)
  40. var car Car
  41. db.First(&car, params["id"])
  42. sqlStatement := `
  43. DELETE FROM services
  44. WHERE car_id = $1;`
  45. err := db.Exec(sqlStatement, params["id"]).Error
  46. if err != nil {
  47. fmt.Println(err)
  48. }
  49. db.Debug().Unscoped().Delete(&car)
  50. json.NewEncoder(w).Encode(&car)
  51. }

希望对你有帮助!

英文:

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

  1. //delete customer
  2. func deleteCustomer(w http.ResponseWriter, r *http.Request) {
  3. params := mux.Vars(r)
  4. setupResponse(&amp;w, r)
  5. if (*r).Method == &quot;OPTIONS&quot; {
  6. return
  7. }
  8. var customer Customer
  9. var cars []Car
  10. db.First(&amp;customer, params[&quot;id&quot;])
  11. db.Model(&amp;customer).Related(&amp;cars)
  12. deleteServicesSqlStatement := `
  13. DELETE FROM services
  14. WHERE car_id = $1;`
  15. for i, car := range cars {
  16. fmt.Println(i, car.ID)
  17. err := db.Exec(deleteServicesSqlStatement, car.ID).Error
  18. if err != nil {
  19. fmt.Println(err)
  20. }
  21. }
  22. DeleteCarsSqlStatement := `
  23. DELETE FROM cars
  24. WHERE customer_id = $1;`
  25. err := db.Exec(DeleteCarsSqlStatement, params[&quot;id&quot;]).Error
  26. if err != nil {
  27. fmt.Println(err)
  28. }
  29. db.Debug().Unscoped().Delete(&amp;customer)
  30. json.NewEncoder(w).Encode(&amp;customer)
  31. }
  32. //delete car
  33. func deleteCar(w http.ResponseWriter, r *http.Request) {
  34. //handle CORS
  35. setupResponse(&amp;w, r)
  36. if (*r).Method == &quot;OPTIONS&quot; {
  37. return
  38. }
  39. params := mux.Vars(r)
  40. var car Car
  41. db.First(&amp;car, params[&quot;id&quot;])
  42. sqlStatement := `
  43. DELETE FROM services
  44. WHERE car_id = $1;`
  45. err := db.Exec(sqlStatement, params[&quot;id&quot;]).Error
  46. if err != nil {
  47. fmt.Println(err)
  48. }
  49. db.Debug().Unscoped().Delete(&amp;car)
  50. json.NewEncoder(w).Encode(&amp;car)
  51. }

<!-- 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:

确定