亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Gorm 多對多關系重復值

Gorm 多對多關系重復值

Go
九州編程 2022-08-01 19:08:04
我正在嘗試在我的演示API中,在 技能和技能列表之間設置多對多關系。Job[]Skill作業結構type Job struct {    ID          string              `sql:"type:uuid;primary_key;"`    Title       string              `json:"title,omitempty"`    Skills      []*skill.Skill      `json:"skills,omitempty"gorm:"many2many:job_skill;"`    CreatedAt   time.Time    UpdatedAt   time.Time}技能結構type Skill struct {    gorm.Model    Name string `json:"name,omitempty"`}然后,我使用 自動生成聯接表。gorm.DB.AutoMigrate()當我向我的 API 發送請求時,數據在第一次時就會正確創建,并且聯接表會按預期方式填充。POST示例數據POST{    "title": "Senior Python Engineer",          "skills": [{"name": "javascript"}, {"name": "python"}]}但是,當我發送添加新技能的請求時,它會復制技能表中的技能,然后在聯接表中為已存在的技能創建新記錄。PATCH示例數據PATCH{    "title": "Lead Engineer",          "skills": [{"name": "javascript"}, {"name": "python"}, {"name": "management"}]}對數據執行 get 請求將顯示以下內容:{    "title": "Lead Engineer",          "skills": [{"name": "javascript"}, {"name": "python"}, {"name": "javascript"}, {"name": "python"}, {"name": "management"}]}我也嘗試過設置所擊中的技能,但是當添加新技能時,它失敗了,因為它說另外兩個已經存在,這很好,但隨后不會添加新的技能。gorm:"unique"Name我假設我只能發回新值?不是整個列表?為了清楚起見,我的一些Go代碼func GetJobs(w http.ResponseWriter, r *http.Request) {    j := &[]Job{}    o := database.DB.Preload("Skills").Find(&j)    render.JSON(w, r, o)}func UpdateJob(w http.ResponseWriter, r *http.Request) {    j := &Job{}    err := json.NewDecoder(r.Body).Decode(j)    if err != nil {        return    }    o := database.DB.Model(&j).Where("id = ?", j.ID).Update(&j)    render.JSON(w, r, o)}
查看完整描述

2 回答

?
眼眸繁星

TA貢獻1873條經驗 獲得超9個贊

這是Gorm聯想的兩件事,我覺得在其文檔中沒有充分傳達,這繼續讓開發人員感到困惑。

1) 它使用 ID 來標識關聯的實體

當您更新該技能列表時,如果它們中沒有要添加的ID,則它們只是要添加的新實體。這會導致您的值重復。即使您有一個字段,如果該字段不是實體的主鍵,則 gorm 將嘗試創建新記錄并導致約束沖突。unique

有幾種方法可以解決這個問題:

  • 確保 API 用戶必須為相關實體提供 ID

  • 通過用戶提供的其他代理鍵從數據庫中提取實體 ID,并將其填充到要保存的實體中。在你的情況下,這可能是因為它是獨一無二的。name

  • 使該代理鍵成為主鍵(使結構成為)。namegorm:"primaryKey"Skill

2) 更新時,它不會刪除關聯切片中未顯示的現有關聯

調用 Save/Update gorm 時,不會刪除集合關聯端的實體。這是一項安全功能,可避免在簡單的保存/更新中意外刪除數據。你必須明確地想要這種行為。

要解決此問題,您可以使用關聯模式替換集合,作為更新的一部分:。db.Model(&job).Association('Skills').Replace(&job.Skills)


查看完整回答
反對 回復 2022-08-01
?
繁花如伊

TA貢獻2012條經驗 獲得超12個贊

詳細闡述Eziquel的答案,并展示什么對我有用。


我更新了我的技能結構,將 用作主鍵Name


type Skill struct {

    Name string `json:"name,omitempty" gorm:"primary_key"`

}

然后,我閱讀了一些文檔,只是使用不確定它的作用,但是沒有它,關聯就會復制或未更新。gorm.DB.Session(&gorm.Session{FullSaveAssociations: true}).Updates(&j)


func UpdateJob(w http.ResponseWriter, r *http.Request) {

    j := &Job{}

    err := json.NewDecoder(r.Body).Decode(j)

    if err != nil {

        return

    }


    database.DB.Session(&gorm.Session{FullSaveAssociations: true}).Updates(&j)

    database.DB.Model(&j).Association("Skills").Replace(&j.Skills)


    render.JSON(w, r, &j)

}

我不知道該怎么辦,但我看到Jihnzu說要在文檔中使用它,沒有進一步的解釋。結合使用,請確保沒有重復項,并且關聯會更新。database.DB.Session(&gorm.Session{FullSaveAssociations: true}).Updates(&j).Association("Skills").Replace(&j.Skills)


如果有多個,你會做的:


database.DB.Session(&gorm.Session{FullSaveAssociations: true}).Updates(&j)

database.DB.Model(&j).Association("Skills").Replace(&j.Skills)

database.DB.Model(&j).Association("Locations").Replace(&j.Locations)


查看完整回答
反對 回復 2022-08-01
  • 2 回答
  • 0 關注
  • 243 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號