简体   繁体   中英

GORM ORM: Preloading in both relationship directions possible?

I would like to know if it is possible to preload data from both sides of a relationship. Consider this example:

type User struct {
    gorm.Model
    Name      string
    Documents []Document // has-many
}
type Document struct {
    gorm.Model
    UserID           uint
    Name             string
    DocumentFulltext DocumentFulltext // has-one
}
type DocumentFulltext struct {
    gorm.Model
    DocumentID uint
    Name       string
}

With that I can easily get the DocumentFulltext for any given document like this

db.Where("id = ?", ID).Preload("DocumentFulltext").Find(&document)

Works!

But what if I have the document and want to preload (or join) the User it belongs to?

db.Where("id = ?", ID).Preload("User").Find(&document)

That gives me a panic. ( invalid memory address )

db.Where("id = ?", ID).Joins("User").Find(&document)

And that produces wonky SQL like .... FROM "documents" User WHERE id =...

How is this possible? Do I need to use "manual" queries?

--

If it is not possible: what is a good-practice / guideline how to model my relationships so I can use GORM built-ins like.Preload() effectively?

Eg If I put the relationship between Users and Documents like this:

type User struct {
    gorm.Model
    Name string
}
type Document struct {
    gorm.Model
    User             User // belongs-to
    UserID           uint
    Name             string
    DocumentFulltext DocumentFulltext // has-one
}
type DocumentFulltext struct {
    gorm.Model
    DocumentID uint
    Name       string
}

then I can preload both, DocumentFulltext AND User, for any given Document. But I loose the ability the preload Documents and Fulltexts if I want to do it for a given User.

--

Any hints a re appreciated. Thx!

Use relation both side means User in Document struct and Documents in User struct

type User struct {
    gorm.Model
    Name      string
    Documents []Document // has-many
}

type Document struct {
    gorm.Model
    UseredID uint
    Name     string
    User   User
}

Then you can preload both sides

db.Debug().Where("id = ?", ID).Preload("User").Find(&document)
db.Debug().Where("id = ?", ID).Preload("Documents").Find(&user)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM