model.go:
type First struct {
ID int `json:"id" gorm:"column:id;primary_key"`
Status string `json:"status" gorm:"column:status"`
SecondID int `json:"second_id" gorm:"column:second_id"`
SecondData Second `json:"second_data" gorm:"foreignKey:SecondID;references:ID"`
}
type Second struct {
ID int `json:"id" gorm:"column:second_id;primary_key"`
Status string `json:"status" gorm:"column:status"`
Description string `json:"description" gorm:"column:description"`
}
var res []model.First
db.Raw("first.*, second.* FROM first LEFT JOIN second ON first.second_id = second.second_id")
db.Preload("SecondData").Find(&res).Error
Output:
{
"id": 1,
"status": "A",
"second_id": 1
"second_data": {
"id": 1
"status": "B",
"description": "blablabla"
}
}
I don't really know how db.Preload() works. Why i should use db.Preload() to get "SecondData" every time i need do nested struct ? Are it's possible only use db.Row() or db.Table().Joins().Where().Find(), i mean's without db.Preload()?
db. Model is the ordinary way of doing things. It allows you to tell gorm which model struct this operation relates to. It isn't always needed, as for example a simple Find with the right struct type will infer the model automatically.
Tags are optional to use when declaring models, GORM supports the following tags: Tags are case insensitive, however camelCase is preferred.
If you want SecondData
loaded every time when the First
struct is loaded without using Preload
, you might consider using hooks.
It might look something like this:
func (f *First) AfterFind(tx *gorm.DB) error {
return tx.First(&f.SecondData, f.SecondID).Error
}
So, when you load the First
data, the AfterFind
hook should be triggered.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With