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.