Я бы хотел использовать принадлежащую 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?