我应该如何使用一个外键引用两个表?

Mik*_*ink 4 go go-gorm

我有一个公司模型和一个客户模型。两者可以是一种关系。

type Customer struct {
    gorm.Model
    Title string
}

type Company struct {
    gorm.Model
    Title string
}

type Relation struct {
    gorm.Model
    CustomerOrCompanyID uint
}
Run Code Online (Sandbox Code Playgroud)

所以两者是有关系的。我怎样才能让我的关系指向公司或客户?

Eze*_*uns 5

在 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
}
Run Code Online (Sandbox Code Playgroud)

现在您可以正常创建记录:

cust := Customer{
    Title: "Cust",
    Rel:   Relation{Foo: "bar"},
}
comp := Company{
    Title: "Comp",
    Rel:   Relation{Foo: "baz"},
}
db.Create(&cust)
db.Create(&comp)
Run Code Online (Sandbox Code Playgroud)

要运行一个查询来获取客户或公司的相关信息,如 @TehSphinX 的前两个查询,您需要执行以下操作:

var cust Customer
db.Joins("Rel").First(&cust, 1)
Run Code Online (Sandbox Code Playgroud)

最后一个查询会更复杂,但也可以使用自定义行结构和联接来完成:

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
Run Code Online (Sandbox Code Playgroud)