Your Question
I want to full load this invoice but I need to omit some column in preload that I want to hide to a paticular user.
The document you expected this should be explained
type TableInvoiceDetail struct {
ID string `gorm:"primary_key;type:uuid;index"`
Parent string `gorm:"type:varchar(36);index"`
TProduct TableProduct `gorm:"foreignKey:Product"`
Product string `gorm:"type:varchar(36);index"`
Quantity int64 `gorm:"type:INT"`
Price decimal.Decimal `gorm:"type:numeric(19,4)"`
Total decimal.Decimal `gorm:"type:numeric(19,4)"`
}
type TableInvoice struct {
ID string `gorm:"primary_key;type:varchar(36);index"`
Date time.Time `gorm:"type:date;index"`
TCustomer TableCustomer `gorm:"foreignKey:Customer"`
Customer string `gorm:"type:varchar(36);index"`
Details []TableInvoiceDetail `gorm:"foreignkey:Parent;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
}
func View(table any) error {
return db.DB.Preload(clause.Associations).Omit(`Customer`, `Details.Product`).Find(table, `table_invoices.id=?`, `I2200001`).Error
}
Actual Result
{
"ID": "IN2200001",
"Date": "2022-07-28T00:00:00Z",
"Customer": "",
"Details": [
{
"ID": "c8f65f15-017e-4fa4-9c44-282893da1a7e",
"Parent": "IN2200001",
"Product": "P00001",
"Quantity": 1,
"Price": "20",
"Total": "20"
}
]
}
Expected answer
{
"ID": "IN2200001",
"Date": "2022-07-28T00:00:00Z",
"Customer": "", // omit Customer here is correct.
"Details": [
{
"ID": "c8f65f15-017e-4fa4-9c44-282893da1a7e",
"Parent": "IN2200001",
"Product": "", // <<--- This one here I want to omit it too.
"Quantity": 1,
"Price": "20",
"Total": "20"
}
]
}
Comment From: a631807682
DB.Preload(..., func(tx *gorm.DB) *gorm.DB {
return tx.Omit("Product")
}).First(...)
https://gorm.io/docs/preload.html#Custom-Preloading-SQL
Comment From: aigoya
@a631807682 Thank you for your help. I've just tried with your solution but it is not working. my gorm version is gorm v1.23.8
Comment From: a631807682
This is a complete example, if it still doesn't work, please create a PR to the playground to describe your problem
func TestGORM(t *testing.T) {
user := User{Name: "jinzhu", Age: 100, Company: Company{Name: "comp"}}
DB.Create(&user)
var result User
if err := DB.Omit("Age").Preload("Company", func(tx *gorm.DB) *gorm.DB {
return tx.Omit("Name")
}).First(&result, user.ID).Error; err != nil {
t.Errorf("Failed, got error: %v", err)
}
if result.Age != 0 ||
result.Company.ID == 0 ||
result.Company.Name != "" {
t.Errorf("preload omit not work")
}
}
Comment From: williamluisan
@a631807682 Hi, is there a way or best practice to omit/remove ID column from Preload? I wish there is a way to hide "ID" (primary key) column that must be selected in Preload Select() or Omit().
Comment From: rafalbraun
add to your model
type Foo struct {
ID int `json:"-"`
}
Comment From: williamluisan
The json:"-" on field ID struct on main model will make the ID wouldn't returned when we do query to model Foo directly.
My case is to omit the ID column when we call the Foo model on Preload, but if use this approach https://github.com/go-gorm/gorm/issues/5551#issuecomment-1200663283, the query will throw error because Preload need to load foreign key column.
I wonder if there's a way to load Preload with foreign key field but not showing it's value on the returned result.