使用 gorm 模型的嵌套结构

Nested structs using gorm model

我有一个名为 User 的结构:

type User struct {
    Email string
    Name string
}

和名为 UserDALModel 的结构:

type UserDALModel struct {
    gorm.Model
    models.User
}

gorm 模型如下所示:

type Model struct {
    ID        uint `gorm:"primary_key"`
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt *time.Time `sql:"index"`
}

这可以使 UserDALModel 与 gorm 模型和用户模型嵌套,因此输出将是:

{
    ID
    CreatedAt
    UpdatedAt
    DeletedAt
    Email 
    Name
}

现在输出是:

{
    Model: {
        ID
        CreatedAt
        UpdatedAt
        DeletedAt
    }
    User: {
        Name
        Email
    }
}

根据 gorm 中的 this test,我认为您需要向结构中添加一个 embedded 标记。

type UserDALModel struct {
    gorm.Model `gorm:"embedded"`
    models.User `gorm:"embedded"`
}

如果需要,您还可以指定前缀 embedded_prefix

我找到了答案:

type UserModel struct {
    Email string
    Name string
}

type UserDALModel struct {
    gorm.Model
    *UserModal
}

------------------------------

user := UserModel{"name", "email@email.com"}
userDALModel := UserDALModel{}
userDal.UserModal = &user

注意在同一列中嵌入两个结构:

package tests

import (
    "fmt"
    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/mysql"
    "testing"
)

type A struct {
    X string
    Y string
}

type B struct {
    X string
    Y string
}

type AB struct {
    B B `gorm:"embedded"` // Embedded struct B before struct A
    A A `gorm:"embedded"`
}

var DB *gorm.DB

func connectDB() error {
    var err error
    spec := "slumberuser:password@tcp(localhost:3306)/slumber"
    DB, err = gorm.Open("mysql", spec+"?parseTime=true&loc=UTC&charset=utf8")
    DB.LogMode(true) // Print SQL statements
    //defer DB.Close()
    if err != nil {
        return err
    }
    return nil
}

// cd tests
// go test -run TestGormEmbed
func TestGormEmbed(t *testing.T) {
    if err := connectDB(); err != nil {
        t.Errorf("error connecting to db %v", err)
    }
    values := []interface{}{&A{}, &B{}}
    for _, value := range values {
        DB.DropTable(value)
    }
    if err := DB.AutoMigrate(values...).Error; err != nil {
        panic(fmt.Sprintf("No error should happen when create table, but got %+v", err))
    }
    DB.Save(&A{X: "AX1", Y: "AY1"})
    DB.Save(&A{X: "AX2", Y: "AY2"})
    DB.Save(&B{X: "BX1", Y: "BY1"})
    DB.Save(&B{X: "BX2", Y: "BY2"})

    //select * from `as` join `bs`;
    //  # x,y,x,y
    //  # AX1,AY1,BX1,BY1
    //  # AX2,AY2,BX1,BY1
    //  # AX1,AY1,BX2,BY2
    //  # AX2,AY2,BX2,BY2

    var abs []AB
    DB.Select("*").
    Table("as").
    Joins("join bs").
        Find(&abs)
    for _, ab := range abs {
        fmt.Println(ab.A, ab.B)
    }
    // if it worked it should print

    //{AX1 AY1} {BX1 BY1}
    //{AX2 AY2} {BX1 BY1}
    //{AX1 AY1} {BX2 BY2}
    //{AX2 AY2} {BX2 BY2}

    // but actually prints
    //{BX1 BY1} {AX1 AY1}
    //{BX1 BY1} {AX2 AY2}
    //{BX2 BY2} {AX1 AY1}
    //{BX2 BY2} {AX2 AY2}
}