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的行也将自动删除。