2017-09-15 264 views
0

我的數據庫中有一個分層模型(一個團隊有客戶,每個客戶可以有筆記)。我的目標是能夠清理數據庫,如果一個團隊被刪除: - >刪除團隊 - >刪除所有客戶 - >刪除每個客戶的所有筆記Go-gorm如果在其他回調中啓動刪除,則不會調用BeforeDelete回調

我的計劃是用BeforeDelete回調,但在團隊回調之後,BeforeDelete for Customers不會被更好地調用。 在數據庫中,團隊被刪除以及其客戶,但客戶的說明不是。日誌行也不會被打印。

您是否知道是否有可能鏈接這些回調,或者是否設計爲第二個回調未執行。

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

回答

0

周圍很多努力之後,我已經找到了解決辦法:

func (team *Team) BeforeDelete(tx *gorm.DB) (err error) { 
    //tx.Where("team_id = ?", team.ID).Delete(Customer{}) 
    var customers []Customer 
    tx.Model(&team).Related(&customers) 

    for _, customer := range customers { 
     tx.Delete(&customer) 
    } 
    return 
} 

而且類似的其他車型。如果有人有更好的建議,我很高興看到它(不知何故,我不喜歡這一個 - 太多的代碼)

+0

它按預期工作,但我不明白主要區別,爲什麼它比問題中的更好。如果有人能指出,我也很高興。謝謝。 – phev8

0

我認爲這是因爲BeforeDelete函數被添加到客戶模型的指針結構。

您剛剛在第一個示例中傳入Customer{},這不是指向模型結構的指針。試試下面的例子嗎?

var customer Customer 
func (team *Team) BeforeDelete(tx *gorm.DB) (err error) { 
    tx.Where("team_id = ?", team.ID).Delete(&customer) 
    return 
} 
+0

感謝您的回覆。在第一行('var customer Customer {}「),我得到語法錯誤,所以我刪除了大括號。但不幸的是,它並沒有解決原始問題。 在BeforeDelete中,我忘記添加但是即使我這樣做,團隊也會被刪除,客戶也會被刪除,但客戶的筆記不會。 我會嘗試將整個腳本添加到問題中,以便任何人都可以測試該行爲。 – phev8

+0

這似乎仍然是真實的,即使在2017年,我也對這種行爲感到驚訝,對於某人執行'db.Delete(Customer {...})'而不是'db.Delete (&Customer {... {)'。儘管看起來至少有一些嘗試總是通過指針類型調用方法:https://github.com/jinzhu/gorm/commit/5174cc5c242a728b435ea2be8a2f7f998e15429b –