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?
type Customer struct {
gorm.Model
FirstName string
LastName string
Phone string `gorm:"typevarchar(100);unique_index"`
Cars []Car `gorm:"constraint:OnDelete:CASCADE;"`
}
type Car struct {
gorm.Model
Make string
Modelo string
Color string
VinNumber string `gorm:"typevarchar(100);unique_index"`
Services []*Service `gorm:"constraint:OnDelete:CASCADE;"`
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(&w, r)
if (*r).Method == "OPTIONS" {
return
}
var customer Customer
db.First(&customer, params["id"])
db.Unscoped().Delete(&customer)
json.NewEncoder(w).Encode(&customer)
}
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)
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
I already tried most of what I seen in StackOverflow and the docs but nothing seems to work so far.
CodePudding user response:
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:"constraint:OnDelete:CASCADE;"
, I also tried db.Select("cars").Delete(&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:
//delete customer
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)
}
//delete car
func deleteCar(w http.ResponseWriter, r *http.Request) {
//handle 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)
}
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>