I'm trying to implement a model for an invoicing application using Go and Gorm. I have defined my Invoice struct and want to include the invoice line items from a separate struct.
type Invoice struct {
Base
CompanyID string `gorm:"not null"`
Company Company
InvoiceNo string `gorm:"not null"`
Currency string `gorm:"not null;default:'GBP'"`
Total float64 `gorm:"not null"`
Terms int `gorm:"not null;default:30"`
IssuedDate time.Time `gorm:"not null"`
DueDate time.Time `gorm:"not null"`
Paid bool `gorm:"not null"`
LineItems []LineItem `gorm:"foreignKey:InvoiceID"`
Void bool `gorm:"default:false"`
}
This is my LineItem struct.
type LineItem struct {
Base
Service string `gorm:"not null"`
Description string `gorm:"not null;"`
Amount float64
Count int
UnitBase string `gorm:"not null;default:'Days'"` // days or hours
Total float64 `gorm:"not null"`
}
When I try to build the application I get the below error.
... got error invalid field found for struct github.com/repo/API/database/models.Invoice's field LineItems: define a valid foreign key for relations or implement the Valuer/Scanner interface
The idea is that I can define a limited set up line items which can be chosen from with fixed rates and descriptions to limit repetition.
I'm unsure if I'm going about this the right/correct way.
So my question is, is it possible to include an array of items from a relational model in this way?
Depending on your column names, there are three ways I can think of how you can achieve this:
Use default syntax (No gorm:foreignKey
)
type Invoice struct {
ID //this is the primary key, may also be in your base model
Lineitems []LineItem
..other fields
}
type LineItem struct {
ID //primary key of LineItem
InvoiceID //automatically this will be your foreign key
..other fields
}
Specifying custom foreign key (lets say second struct has a different column name which you want as the foreignKey)
type Invoice struct {
ID //this is the primary key, may also be in your base model
Lineitems []LineItem `gorm:"foreignKey:ParentID"`
..other fields
}
type LineItem struct {
ID //primary key of LineItem
ParentID //this is the custom column referencing Invoice.ID
..other fields
}
Or both structs have different column names
type Invoice struct {
ID //this is the primary key, may also be in your base model
InvoiceNum
Lineitems []LineItem `gorm:"foreignKey:ParentNum;references:InvoiceNum"`
..other fields
}
type LineItem struct {
ID //primary key of LineItem
ParentNum //this is now referencing Invoice.InvoiceNum
..other fields
}