0

I am using GoFiber, GORM and mysql database. I am writing POST METHOD to write product data to DB. I see the data type I'm trying to write is "nested data" or "unmarshal data", but there's not much documentation for golang or specifically GORM Many2Many for POST METHOD.

The structures that I use:

package models

type Product struct {
  Model
  Code        string  `json:"code"`
  Title       string  `json:"title"`
  Description string  `json:"description"`
  Image       string  `json:"image"`
  Price       float64 `json:"price"`
  Stocks      []Stock `json:"stock,omitempty" gorm:"many2many:product_stocks;"`
}

type Stock struct {
  Model
  Size      string  `json:"size"`
  Color     string  `json:"color"`
  Quantity  int     `json:"quantity"` 
}

Json data:

{
  "code": "SS2022VNMNYU7W",
  "title": "Title Demo",
  "description": "Description Demo",
  "image": "path",
  "price": "100",
  "stock": [
    {
      "size": "m",
      "color": "red",
      "quantity": "50"
    },
    {
      "size": "m",
      "action": "yellow",
      "quantity": "50"
    },
    {
      "size": "l",
      "action": "red",
      "quantity": "20"
    },
    {
      "size": "l",
      "action": "blue",
      "quantity": "30"
    }
  ]
 }

Here is the code I'm working with:

func CreateProduct(c *fiber.Ctx) error {
  var data map[string]string
  if err := c.BodyParser(&data); err != nil {
    return err
  }
  
  PriceItem, _ := strconv.Atoi(data["price"])
  product := models.Product{
    Code:         data["code"],
    Title:        data["title"],
    Description:  data["description"],
    Image:        data["image"],
    Price:        PriceItem,
    
    /* here, I don't know how to input stock into product data because this stock varies by product. For example, changes in the number of sizes, changes in the number of colors. */
    Stocks: []models.Stock{
      {
        Size:     "size",
        Color:    "color",
        Quantity: "quantity", /* Converting Strings to Numbers */
      },
    },
  }
  database.DB.Create(&product)
  
  return c.JSON(product)
}
Chandan
  • 11,465
  • 1
  • 6
  • 25
  • "nested data" or "unmarshal data" `gorm:"-"` (like json `json:"-"` ) here: https://gorm.io/docs/models.html `ignore this field, - no read/write permission, -:migration no migrate permission, -:all no read/write/migrate permission` – Para Jun 10 '22 at 09:45
  • if you want change the number of sizes, you can use hook https://gorm.io/docs/hooks.html or Customize Data Types https://gorm.io/docs/data_types.html – Para Jun 10 '22 at 09:56

1 Answers1

1

In json you can directly pass price and quantity has integer and then you can directly use Product model with BodyParser

{
  "code": "SS2022VNMNYU7W",
    "title": "Title Demo",
    "description": "Description Demo",
    "image": "path",
    "price": 100, <- as int
    "stock": [
    {
      "size": "m",
      "color": "red",
      "quantity": 50 <- as int
    },
    {
      "size": "m",
      "action": "yellow",
      "quantity": 50 <- as int
    },
    {
      "size": "l",
      "action": "red",
      "quantity": 20 <- as int
    },
    {
      "size": "l",
      "action": "blue",
      "quantity": 30 <- as int
    }
  ]
}

Then in CreatePost method

func CreateProduct(c *fiber.Ctx) error {
  product := new(Product)
  if err := c.BodyParser(&product); err != nil {
    return err
  }
  
  database.DB.Create(&product)
  
  return c.JSON(product)
}
Chandan
  • 11,465
  • 1
  • 6
  • 25
  • Result for this solution (Thunder Client): 405 Method Not Allowed I have adjusted the product variable to match the function of Gofiber: func CreateProduct(c *fiber.Ctx) error { var product models.Product if err := c.BodyParser(&product); err != nil { return err } database.DB.Create(&product) return c.JSON(product) } – Zirene Nguyễn Jun 10 '22 at 11:42
  • @ZireneNguyễn please share the request you are making and have you registered is has get or post method ? – Chandan Jun 10 '22 at 11:51
  • This is good activity code: func CreateProduct(c *fiber.Ctx) error { product := new(models.Product) if err := c.BodyParser(&product); err != nil { return err } database.DB.Create(&product) /* return c.JSON(user) */ return c.JSON(fiber.Map{ "StatusCode": http.StatusOK, "message": "Created successfully", }) } – Zirene Nguyễn Jun 11 '22 at 21:26
  • Thank you so much! But can I expand the question to delete, update methods. – Zirene Nguyễn Jun 11 '22 at 21:27
  • @ZireneNguyễn yes you can update the question – Chandan Jun 13 '22 at 07:11