I currently have a bit of unique situation where I think I don’t want to make a table for a struct because it’s not gonna be used by other parts of the system other than the struct/table that needs it. Also the child struct only have a few fields, so I think I’d just save it as a string. Here’s the structs involved:
<code>type LivestockSpecies int
const (
Chicken LivestockSpecies = iota + 1
Goat
Cattle
Carabao
Horse
Swine
)
type Sex int
const (
Male Sex = iota + 1
Female
)
type ShippingDocLivestockRecord struct {
LivestockSpecies LivestockSpecies `json:"livestock_species"`
HeadCount int32 `json:"head_count"`
Sex Sex `json:"sex"`
Remarks string `json:"remarks"`
}
type ShippingDoc struct {
gorm.Model
ID string `gorm:"primarykey; size:40;"`
ValidUntil string `json:"valid_until"`
QRCodeVal string `json:"qr_code_val"`
Destination User `gorm:"foreignKey:DestinationID; constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"destination"`
DestinationID string `gorm:"size:40; index; not null" json:"destination_id"`
IncludeVHCs []VHCApplication `gorm:"many2many:shipping_doc_included_vhcs;" json:"included_vhcs"`
IssuanceDate string `gorm:"column:issuance_date"`
ControlNumber string `json:"control_number"`
SharedToHauler User `gorm:"foreignKey:SharedToHaulerID; constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"shared_to_hauler"`
SharedToHaulerID string `gorm:"size:40; index; not null" json:"shared_to_hauler_id"`
Remarks string `json:"remarks"`
IssuedByProvetRep User `gorm:"foreignKey:IssuedByProvetRepID; constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"issued_by_provet_rep"`
IssuedByProvetRepID string `gorm:"size:40; index; not null" json:"issued_by_provet_rep_id"`
IsRequestedByGrower bool `json:"is_requested_by_grower"`
IsRequestedByHauler bool `json:"is_requested_by_hauler"`
Vehicle User `gorm:"foreignKey:VehicleID; constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"vehicle"`
VehicleID string `gorm:"size:40; index; not null" json:"vehicle_id"`
ShipmentDate string `json:"shipment_date"`
LivestockDetails []ShippingDocLivestockRecord `json:"livestock_details"`
}
</code>
<code>type LivestockSpecies int
const (
Chicken LivestockSpecies = iota + 1
Goat
Cattle
Carabao
Horse
Swine
)
type Sex int
const (
Male Sex = iota + 1
Female
)
type ShippingDocLivestockRecord struct {
LivestockSpecies LivestockSpecies `json:"livestock_species"`
HeadCount int32 `json:"head_count"`
Sex Sex `json:"sex"`
Remarks string `json:"remarks"`
}
type ShippingDoc struct {
gorm.Model
ID string `gorm:"primarykey; size:40;"`
ValidUntil string `json:"valid_until"`
QRCodeVal string `json:"qr_code_val"`
Destination User `gorm:"foreignKey:DestinationID; constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"destination"`
DestinationID string `gorm:"size:40; index; not null" json:"destination_id"`
IncludeVHCs []VHCApplication `gorm:"many2many:shipping_doc_included_vhcs;" json:"included_vhcs"`
IssuanceDate string `gorm:"column:issuance_date"`
ControlNumber string `json:"control_number"`
SharedToHauler User `gorm:"foreignKey:SharedToHaulerID; constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"shared_to_hauler"`
SharedToHaulerID string `gorm:"size:40; index; not null" json:"shared_to_hauler_id"`
Remarks string `json:"remarks"`
IssuedByProvetRep User `gorm:"foreignKey:IssuedByProvetRepID; constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"issued_by_provet_rep"`
IssuedByProvetRepID string `gorm:"size:40; index; not null" json:"issued_by_provet_rep_id"`
IsRequestedByGrower bool `json:"is_requested_by_grower"`
IsRequestedByHauler bool `json:"is_requested_by_hauler"`
Vehicle User `gorm:"foreignKey:VehicleID; constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"vehicle"`
VehicleID string `gorm:"size:40; index; not null" json:"vehicle_id"`
ShipmentDate string `json:"shipment_date"`
LivestockDetails []ShippingDocLivestockRecord `json:"livestock_details"`
}
</code>
type LivestockSpecies int
const (
Chicken LivestockSpecies = iota + 1
Goat
Cattle
Carabao
Horse
Swine
)
type Sex int
const (
Male Sex = iota + 1
Female
)
type ShippingDocLivestockRecord struct {
LivestockSpecies LivestockSpecies `json:"livestock_species"`
HeadCount int32 `json:"head_count"`
Sex Sex `json:"sex"`
Remarks string `json:"remarks"`
}
type ShippingDoc struct {
gorm.Model
ID string `gorm:"primarykey; size:40;"`
ValidUntil string `json:"valid_until"`
QRCodeVal string `json:"qr_code_val"`
Destination User `gorm:"foreignKey:DestinationID; constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"destination"`
DestinationID string `gorm:"size:40; index; not null" json:"destination_id"`
IncludeVHCs []VHCApplication `gorm:"many2many:shipping_doc_included_vhcs;" json:"included_vhcs"`
IssuanceDate string `gorm:"column:issuance_date"`
ControlNumber string `json:"control_number"`
SharedToHauler User `gorm:"foreignKey:SharedToHaulerID; constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"shared_to_hauler"`
SharedToHaulerID string `gorm:"size:40; index; not null" json:"shared_to_hauler_id"`
Remarks string `json:"remarks"`
IssuedByProvetRep User `gorm:"foreignKey:IssuedByProvetRepID; constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"issued_by_provet_rep"`
IssuedByProvetRepID string `gorm:"size:40; index; not null" json:"issued_by_provet_rep_id"`
IsRequestedByGrower bool `json:"is_requested_by_grower"`
IsRequestedByHauler bool `json:"is_requested_by_hauler"`
Vehicle User `gorm:"foreignKey:VehicleID; constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"vehicle"`
VehicleID string `gorm:"size:40; index; not null" json:"vehicle_id"`
ShipmentDate string `json:"shipment_date"`
LivestockDetails []ShippingDocLivestockRecord `json:"livestock_details"`
}
The compiler told me that I might need a valuer/scanner interface for my usecase, but I can’t make it work so far. Here’s what I currently have.
<code>type LivestockRecords []ShippingDocLivestockRecord
func (lr *LivestockRecords) Scan(value interface{}) (err error) {
var data []byte
switch v := value.(type) {
case []byte:
data = v
case string:
data = []byte(v)
case nil:
return nil
default:
return fmt.Errorf("unsupported type: %T", value)
}
if len(data) == 0 {
return nil
}
var sdlrArr []ShippingDocLivestockRecord
mErr := json.Unmarshal(data, &sdlrArr)
if mErr != nil {
panic(mErr)
}
for _, v := range sdlrArr {
*lr = append(*lr, v)
}
return mErr
}
func (lr LivestockRecords) Value() (driver.Value, error) {
if lr == nil {
return nil, nil
}
blr, err := json.Marshal(lr)
if err != nil {
panic(err)
}
return blr, nil
}
</code>
<code>type LivestockRecords []ShippingDocLivestockRecord
func (lr *LivestockRecords) Scan(value interface{}) (err error) {
var data []byte
switch v := value.(type) {
case []byte:
data = v
case string:
data = []byte(v)
case nil:
return nil
default:
return fmt.Errorf("unsupported type: %T", value)
}
if len(data) == 0 {
return nil
}
var sdlrArr []ShippingDocLivestockRecord
mErr := json.Unmarshal(data, &sdlrArr)
if mErr != nil {
panic(mErr)
}
for _, v := range sdlrArr {
*lr = append(*lr, v)
}
return mErr
}
func (lr LivestockRecords) Value() (driver.Value, error) {
if lr == nil {
return nil, nil
}
blr, err := json.Marshal(lr)
if err != nil {
panic(err)
}
return blr, nil
}
</code>
type LivestockRecords []ShippingDocLivestockRecord
func (lr *LivestockRecords) Scan(value interface{}) (err error) {
var data []byte
switch v := value.(type) {
case []byte:
data = v
case string:
data = []byte(v)
case nil:
return nil
default:
return fmt.Errorf("unsupported type: %T", value)
}
if len(data) == 0 {
return nil
}
var sdlrArr []ShippingDocLivestockRecord
mErr := json.Unmarshal(data, &sdlrArr)
if mErr != nil {
panic(mErr)
}
for _, v := range sdlrArr {
*lr = append(*lr, v)
}
return mErr
}
func (lr LivestockRecords) Value() (driver.Value, error) {
if lr == nil {
return nil, nil
}
blr, err := json.Marshal(lr)
if err != nil {
panic(err)
}
return blr, nil
}
I’m not strongly against giving the child struct a table, but I just want to explore some new ways of doing things