在Go Gorm中添加具有多对多反向引用的记录



Go Gorm中编写和更新回引用多对多结构的记录的方法是什么。

例如,我有一个具有自引用Related属性的Contact结构:

type Contact struct {
gorm.Model
FirstName  string      `json:"first_name"`
LastName   string      `json:"last_name"`
MiddleName string      `json:"middle_name,omitempty"`
Related    []Contact   `json:"related,omitempty" gorm:"many2many:related_contacts"`
}

填充两个联系人,每个联系人引用另一个

fred := model.Contact{
FirstName:  "Fred",
LastName:   "Jones",
MiddleName: "B",
}
bill := model.Contact{
FirstName:  "Bill",
LastName:   "Brown",
MiddleName: "R",
}
fred.Related = []model.Contact{bill}
bill.Related = []model.Contact{fred}

执行db.Save(&fred)将向数据库写入两条记录;一个用于bill,一个用于fred,然而,bill记录没有对fred的反向引用(因为它还没有添加,也没有ID(。

如果我也执行db.Save(&bill),我现在得到4条记录,因为保存比尔不知道fred已经保存了。

虽然我确实意识到我可以保存一个,然后找到第二个并更新它,但我想知道是否有更好的";Gorm Way";在添加记录时不必手动保持后台引用同步的情况下执行此操作?

此外,如果弗雷德被免职,该怎么办?我需要手动处理related_contacts表吗?

我认为您遇到的问题是bill.Related中的fred是一个副本,因此无法通过调用db.Save(&fred)来更新其ID。

当您调用Save时,gorm会检查任何模型的ID字段,以确定它是否应该创建或更新该模型。

我会尝试的是:

fred := model.Contact{
FirstName:  "Fred",
LastName:   "Jones",
MiddleName: "B",
}
db.Save(&fred)
bill := model.Contact{
FirstName:  "Bill",
LastName:   "Brown",
MiddleName: "R",
Related:    []model.Contact{fred},
}
db.Save(&bill)
// Now both bill and fred have IDs
fred.Related = []model.Contact{bill}
db.Save(&fred)

这里需要注意的一件事是gorm是否试图保存fred.Related[0]并进入无限循环。你可以通过跳过关联的扰乱来管理这一点。所以这意味着你将把最后两行改为:

fred.Related = []model.Contact{bill}
db.Omit("Related.*").Save(&fred)

// or using association mode
db.Model(&fred).Association("Related").Append(&bill)

编辑:关于删除。对您正在使用的数据库一无所知,您通常必须自己管理相关的实体删除。如果使用的数据库支持外键约束,则可以将联接表外键声明为REFERENCES contacts(id) ON DELETE CASCADE。这意味着,如果删除任何Contact,联接表中包含相同ID的行也将自动删除。

最新更新