Предварительная загрузка «принадлежит» ассоциациям в обе стороны - PullRequest
1 голос
/ 13 января 2020

Я бы хотел использовать принадлежащую GORM ассоциацию способом, подобным отношениям Django один к одному . Рассмотрим следующий пример, в котором каждый User связан с одним Profile:

package main

import (
    "fmt"
    "os"

    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/sqlite"
    "github.com/sirupsen/logrus"
)

type User struct {
    gorm.Model
    Name string
}

func (user User) String() string {
    return fmt.Sprintf("User(Name=%s)", user.Name)
}

type Profile struct {
    gorm.Model
    UserID uint
    User   User
    Name   string
}

func (profile Profile) String() string {
    return fmt.Sprintf("Profile(Name=%s, User=%d)", profile.Name, profile.UserID)
}

func (user *User) AfterCreate(scope *gorm.Scope) error {
    profile := Profile{
        UserID: user.ID,
        Name:   user.Name,
    }

    return scope.DB().Create(&profile).Error
}

const dbName = "examplegorm.db"

func main() {
    db, err := gorm.Open("sqlite3", dbName)
    if err != nil {
        logrus.Fatalf("open db: %v", err)
    }
    defer func() {
        db.Close()
        os.Remove(dbName)
    }()

    db.LogMode(true)
    db.AutoMigrate(&User{})
    db.AutoMigrate(&Profile{})

    user := User{Name: "jinzhu"}
    if err := db.Create(&user).Error; err != nil {
        logrus.Fatalf("create user: %v", err)
    }

    var profile Profile
    if err := db.Where(Profile{UserID: user.ID}).Preload("User").First(&profile).Error; err != nil {
        logrus.Fatalf("get profile: %v", err)
    }

    logrus.Infof("profile: %v", profile)
    logrus.Infof("user: %v", profile.User)
}

. В этом примере я запрашиваю Profile и предварительно загружаю его User. Однако на самом деле я хотел бы сделать это по-другому: запросить User и предварительно загрузить Profile.

Как я понимаю, в Django вы сможете получить доступ к обоим profile.user и user.profile, но если я пытаюсь добавить поля Profile и ProfileID к модели User,

type User struct {
    gorm.Model
    Name string
    Profile
    ProfileID uint
}

я получаю ошибку «недопустимый рекурсивный тип»:

# command-line-arguments
./gorm_belongs_to.go:23:6: invalid recursive type Profile

Есть ли способ получить user.Profile в этом примере GORM?

1 Ответ

0 голосов
/ 13 января 2020

Я думаю, что проблема в вашем случае заключается в использовании имени Profile, которое совпадает с типом. Если ваша User структура будет выглядеть примерно так, она должна работать:

 type User struct {
    gorm.Model
    Name string
    UserProfile Profile
    UserProfileID uint
}
...