J'ai un modèle hiérarchique dans ma base de données (une équipe a des clients et chaque client peut avoir des notes). Mon objectif serait de pouvoir nettoyer la base de données si une équipe est supprimée: -> supprimer l'équipe -> supprimer tous les clients -> supprimer toutes les notes pour chaque clientGo-gorm BeforeDelete callback n'est pas appelé si delete est démarré dans un autre callback
Mon plan était de le faire avec le rappel BeforeDelete, mais après le callback de l'équipe, le BeforeDelete pour les clients n'est plus appelé correctement. Dans la base de données, l'équipe est supprimée ainsi que ses clients, mais pas les notes pour les clients. La ligne de journal n'est pas imprimée non plus. Savez-vous s'il est possible d'enchaîner ces rappels ou si c'est par conception que le second rappel n'est pas effectué?
package main
import (
"errors"
"log"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
)
var DB *gorm.DB
type Team struct {
gorm.Model
Name string
Customers []Customer
}
type Note struct {
gorm.Model
Content string
OwnerID uint
OwnerType string
}
type Customer struct {
gorm.Model
Name string
TeamID uint
Notes []Note `gorm:"polymorphic:Owner;"`
}
func (team *Team) BeforeDelete(tx *gorm.DB) (err error) {
log.Println("------- delete team ---------")
tx.Where("team_id = ?", team.ID).Delete(&Customer{})
return
}
func (customer *Customer) BeforeDelete(tx *gorm.DB) (err error) {
log.Println("------- delete customer ---------")
tx.Where("owner_type = ? AND owner_id = ?", "customers", customer.ID).Delete(&Note{})
return
}
func (note *Note) BeforeDelete(tx *gorm.DB) (err error) {
log.Println("------- delete note ---------")
return
}
func init() {
var err error
DB, err = gorm.Open("sqlite3", "data.DB")
if err != nil {
log.Printf("Error from gorm.Open: %s\n", err)
}
log.Println("You connected to your database.")
if DB.HasTable(&Team{}) {
DB.DropTable(&Team{})
DB.DropTable(&Customer{})
DB.DropTable(&Note{})
}
if !DB.HasTable(&Team{}) {
DB.CreateTable(&Team{})
}
if !DB.HasTable(&Customer{}) {
DB.CreateTable(&Customer{})
}
if !DB.HasTable(&Note{}) {
DB.CreateTable(&Note{})
}
}
func createTeam(name string) Team {
team := Team{Name: name}
DB.Create(&team)
return team
}
func addCustomer(teamID uint, name string) Customer {
customer1 := Customer{Name: name}
customer1.TeamID = teamID
customer1.Notes = []Note{}
DB.Create(&customer1)
return customer1
}
func addNoteToCustomer(customerID uint, note Note) (customer Customer, err error) {
if DB.Preload("Notes").First(&customer, customerID).RecordNotFound() {
return customer, errors.New("customer doesn't exists")
}
customer.Notes = append(customer.Notes, note)
DB.Save(&customer)
return customer, err
}
func main() {
team := createTeam("Team 1")
team2 := createTeam("Team 2")
// Create customers
customer1 := addCustomer(team.ID, "TestC 1")
customer2 := addCustomer(team.ID, "TestC 2")
customer3 := addCustomer(team2.ID, "TestC 3")
customer4 := addCustomer(team2.ID, "TestC 4")
note1 := Note{Content: "testcontent"}
addNoteToCustomer(customer1.ID, note1)
note2 := Note{Content: "testcontent 2"}
addNoteToCustomer(customer2.ID, note2)
note3 := Note{Content: "testcontent 3"}
addNoteToCustomer(customer3.ID, note3)
note4 := Note{Content: "testcontent 4"}
addNoteToCustomer(customer4.ID, note4)
DB.Delete(&team)
}
Cela fonctionne comme prévu, mais je ne peux pas comprendre la différence majeure, pourquoi est-ce mieux que celui de la question. Si quelqu'un peut le signaler, je suis également content. Merci. – phev8