Riki
Riki

Reputation: 341

GORM panics when `gorm.Model` not embedded

This is my model. Note that I don't want to embed gorm.Model into my structs.

type Order struct {
    OrderID   uint64     `gorm:"column:order_id" gorm:"primaryKey" gorm:"unique"`
    Cart      Cart       `gorm:"foreignKey:UserID"`
    CreatedBy UserID     `gorm:"index"`
    CreatedAt *time.Time `gorm:"autoCreateTime:nano"`
    UpdatedAt *time.Time `gorm:"autoUpdateTime:nano"`
    DeletedAt *time.Time
}

type Category struct {
    ID        uint64     `gorm:"column:category_id" gorm:"primaryKey" gorm:"unique"`
    Name      string     `gorm:"index"`
    Image     string     
    Products  []Product  `gorm:"foreignKey:product_id" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
    CreatedBy UserID     `gorm:"index" gorm:"type:bytea"`
    CreatedAt *time.Time `gorm:"autoCreateTime:nano"`
    UpdatedAt *time.Time `gorm:"autoUpdateTime:nano"`
    DeletedAt *time.Time 
}

type Cart struct {
    UserID    UserID     `gorm:"column:user_id" gorm:"primaryKey"`
    Products  []Product  `gorm:"foreignKey:ID"`
    Price     float64   
    CreatedAt *time.Time `gorm:"autoCreateTime:nano"`
    UpdatedAt *time.Time `gorm:"autoUpdateTime:nano"`
    DeletedAt *time.Time 
}

type Product struct {
    ID        uint64     `gorm:"column:product_id" gorm:"primaryKey" gorm:"unique"`
    Name      string     `gorm:"index"`
    Price     float64    `gorm:"index"`
    Rating    uint       `gorm:"index"`
    Image     string     
    CreatedBy UserID     `gorm:"index" gorm:"type:bytea"`
    CreatedAt *time.Time `gorm:"autoCreateTime:nano"`
    UpdatedAt *time.Time `gorm:"autoUpdateTime:nano"`
    DeletedAt *time.Time 
}

When I use AutoMigrate, I get the following errors:

[error] invalid field found for struct moonspace/model.Cart's field Products: define a valid foreign key for relations or implement the Valuer/Scanner interface

I have tried changing the foreignKey:UserID to foreignKey:user_id but the error remains the same.

Here is my auto-migrate:

func createPostgresCLI(cfg types.Config, config ...any) *gorm.DB {
    db, err := gorm.Open(postgres.Open(cfg.Url))
    if err != nil {
        panic(err)
    }

    err = db.AutoMigrate(&model.Order{}, &model.Cart{}, &model.Category{}, &model.Product{})
    if err != nil {
        panic(fmt.Errorf("Error creating database: %w", err))
    }

    return db
}

What am I doing wrong? Also, when I use gorm.Model, and when I try to insert a Product into a Category, I'm getting a foreign key constraint error. I'm trying to add it through associations.

Upvotes: 1

Views: 212

Answers (1)

user19812413
user19812413

Reputation:

Category <==> Product: foreign key column needs to be included in Product which will reference Category ID. CUrrent config when working will update product ID with category ID, which will be wrong

type Category struct {
    ID       uint64 `gorm:"column:category_id;primaryKey"`
    Products  []Product  `gorm:"foreignKey:CategoryID" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
    ....
}

type Product struct {
    ID        uint64     `gorm:"column:product_id" gorm:"primaryKey" gorm:"unique"`
    CategoryID uint64 // New field to hold category ID.
    ....
}

Cart <===> Product relation can be modelled as many2many with a join table to store products' and carts' IDs, might not need foreign key here.

type Cart struct {
    CartID   uint64 `gorm:"primaryKey"`
    Products []Product `gorm:"many2many:cart_products"`
    ....
}

Also You can use combine all gorm tags into one, no need for repeating.

Upvotes: 1

Related Questions