go - 我应该如何使用一个外键引用两个表?
问题描述
我有一个公司模型,我有一个客户模型。两者都可以是关系。
type Customer struct {
gorm.Model
Title string
}
type Company struct {
gorm.Model
Title string
}
type Relation struct {
gorm.Model
CustomerOrCompanyID uint
}
所以两者是有关系的。我怎样才能让我的关系指向公司或客户?
解决方案
有一种方法可以在 Gorm 中使用多态的 Has One 关系自然地做到这一点。这将使您能够轻松运行@TheSphinX 提供的一些查询。
但是,您需要在关系表中添加类型鉴别器列才能使其工作:
type Customer struct {
gorm.Model
Title string
Rel Relation `gorm:"polymorphic:Owner"`
}
type Company struct {
gorm.Model
Title string
Rel Relation `gorm:"polymorphic:Owner"`
}
type Relation struct {
gorm.Model
Foo string
OwnerID uint
OwnerType string
}
现在您可以正常创建记录:
cust := Customer{
Title: "Cust",
Rel: Relation{Foo: "bar"},
}
comp := Company{
Title: "Comp",
Rel: Relation{Foo: "baz"},
}
db.Create(&cust)
db.Create(&comp)
要运行获取 Customer 或 Company 以及 @TehSphinX 的前两个查询中的相关信息的查询,您可以执行以下操作:
var cust Customer
db.Joins("Rel").First(&cust, 1)
最后一个查询会更复杂,但也可以使用自定义行结构和连接来完成:
var rows []struct {
Relation
Customer Customer `gorm:"embedded;embeddedPrefix:cust_"`
Company Company `gorm:"embedded;embeddedPrefix:comp_"`
}
db.Select(`
relations.*,
customers.id AS cust_id,
customers.title AS cust_title,
companies.id AS comp_id,
companies.title AS comp_title
`).
Model(&Relation{}).
Joins("LEFT JOIN customers ON relations.owner_id = customers.id AND relations.owner_type = 'customers'").
Joins("LEFT JOIN companies ON relations.owner_id = companies.id AND relations.owner_type = 'companies'").
Find(&rows)
// now rows[i].Relation is filled, and rows[i].Customer or rows[i].Company
// are non-zero depending on rows[i].Relation.OwnerType
推荐阅读
- apache-flink - Flink 1.6 Async IO - 如何在丰富流时增加吞吐量,使用 REST 服务调用?
- python - 使用 pandas 过滤具有特定条件的列的简单工具
- spring - 使用 RestController 接受字符串和 XML 数据
- asp.net-mvc-4 - 如何在 MVC 中将文本框布局显示为文本框而无需在侧面下拉?
- javascript - 从 aspx.cs 调用 ASP.NET 母版页 (.Master) 中的函数
- javascript - 过去 7 天内创建的记录的水线查询?
- javascript - 如何在“pdfmake”javascript库中设置水印的字体大小
- java - 如何在方法中输入数组作为参数?
- angular - 在 Angular 5 中动态加载子组件
- javascript - Reactjs,在另一个方法中使用 ref 调用函数,未捕获 TypeError