0
votes

I am attempting to write my first app in golang, I have a json structure which I am trying to parse and store to DB using golang GORM. In the json structure I have multiple similar price structures like given below. I am attempting to make one common struct for all kinds of price set and reuse the same price set structure for all types of price sets occurring any where in the json (there are several other price set types with same structure).

Sample Source json -

"price_set": {
    "shop_money": {
        "amount": "5.00",
        "currency_code": "USD"
    },
    "presentment_money": {
        "amount": "5.00",
        "currency_code": "USD"
    }
},
"total_discount_set": {
    "shop_money": {
        "amount": "0.00",
        "currency_code": "USD"
    },
    "presentment_money": {
        "amount": "0.00",
        "currency_code": "USD"
    }
}

This is what I have attempted to do with my GO code. However I am running into issues with foreign keys and I am not sure this is the best way to go about this.

type Order struct {
    ID                     int64      `json:"id,omitempty"`
    OrderStatusURL         string     `json:"order_status_url,omitempty"`
    PresentmentCurrency    string     `json:"presentment_currency,omitempty"`
    TotalLineItemsPriceSet PriceSet   `json:"total_line_items_price_set,omitempty"`
    TotalDiscountSet       PriceSet   `json:"total_discounts_set,omitempty"`
    TotalShippingPriceSet  PriceSet   `json:"total_shipping_price_set,omitempty"`
    SubTotalPriceSet       PriceSet   `json:"subtotal_price_set,omitempty"`
    TotalPriceSet          PriceSet   `json:"total_price_set,omitempty"`
    TotalTaxSet            PriceSet   `json:"total_tax_set,omitempty"`
}

type PriceSet struct {
    ShopMoney        CurrencyHolder `json:"shop_money,omitempty"`
    PresentmentMoney CurrencyHolder `json:"presentment_money,omitempty"`
}

type CurrencyHolder struct {
    Amount       string `json:"amount,omitempty"`
    CurrencyCode string `json:"currency_code,omitempty"`
}

This implementation is giving me the error

[error] invalid field found for struct github.com/proj/proj-api/models.PriceSet's field ShopMoney, need to define a valid foreign key for relations or it need to implement the Valuer/Scanner interface

Edit -- Added calling code --

func CreateOrderTables(db *gorm.DB) {
    db.AutoMigrate(&models.Order{})
}

called from

func CreateOrderTables(c *gin.Context) {
    DB := helper.OpenDBService()
    helper.CreateOrderTables(DB)
    close(DB, c, "Order tables created")
}
1
can you give more context to this? and how to reproduce the error? - Jakub Dóka
I am trying to parse the json shared at the the top by the GORM structs shared in the code - Ayon
no i mean can you share the code that does the thing, otherwise i have to guess what function returned the error - Jakub Dóka
Added to main body of question - Ayon

1 Answers

0
votes

The error you are seeing is coming from the fact that you've included a set of structs in your Order entity but you have not told GORM what the relationship is with these structs. Generally speaking, gorm treats structs inside your entity struct as related entities (tables).

The way way you have laid out your JSON structure it is ambiguous how best to map to a simple relational design. The easiest I can think of is to have all these fields be in the same huge table by using gorm:"embedded", which puts these struct fields in the same table:

type Order struct {
    ID                     int64    `json:"id,omitempty"`
    OrderStatusURL         string   `json:"order_status_url,omitempty"`
    PresentmentCurrency    string   `json:"presentment_currency,omitempty"`
    TotalLineItemsPriceSet PriceSet `json:"total_line_items_price_set,omitempty" gorm:"embedded;embeddedPrefix:total_line_items_"`
    TotalDiscountSet       PriceSet `json:"total_discounts_set,omitempty"  gorm:"embedded;embeddedPrefix:total_discount_"`
    TotalShippingPriceSet  PriceSet `json:"total_shipping_price_set,omitempty"  gorm:"embedded;embeddedPrefix:total_shipping_"`
    SubTotalPriceSet       PriceSet `json:"subtotal_price_set,omitempty"  gorm:"embedded;embeddedPrefix:subtotal_"`
    TotalPriceSet          PriceSet `json:"total_price_set,omitempty"  gorm:"embedded;embeddedPrefix:total_"`
    TotalTaxSet            PriceSet `json:"total_tax_set,omitempty"  gorm:"embedded;embeddedPrefix:total_tax_"`
}

type PriceSet struct {
    ShopMoney        CurrencyHolder `json:"shop_money,omitempty" gorm:"embedded;embeddedPrefix:shop_"`
    PresentmentMoney CurrencyHolder `json:"presentment_money,omitempty" gorm:"embedded;embeddedPrefix:presentment_"`
}

type CurrencyHolder struct {
    Amount       string `json:"amount,omitempty"`
    CurrencyCode string `json:"currency_code,omitempty"`
}

This works, though it isn't a very nice (read: normalized) design. You might want to think about the relational structure of your data and how it is best represented as tables in a database rather than designing the JSON first :)