Home  >  Article  >  Backend Development  >  GORM Find(&room) operation fills structure with empty data instead of actual data

GORM Find(&room) operation fills structure with empty data instead of actual data

王林
王林forward
2024-02-08 22:10:08897browse

GORM Find(&room) 操作用空数据而不是实际数据填充结构

php editor Xiaoxin found that when using GORM's Find(&room) operation, sometimes empty data is used to fill the structure instead of using actual data. This may cause errors or exceptions in the program. In order to solve this problem, we need to understand how GORM works and how to correctly use the Find operation to fill the structure to avoid this situation from happening. In this article, we will detail the cause of this problem and provide solutions to ensure correct use of GORM's Find operation.

Question content

I am using GORM to connect to my database. I'm using GoFiber for this application. I have two endpoints, a GET to list all rooms and a POST to create rooms. I'm using the Gorm MySQL driver and connecting to a database hosted by PlanetScale.

My model:-

type Room struct {
    Model
    RoomType string `json:"room_type" validate:"required"`
}

My get endpoint code: -

func GetAllRooms(c *fiber.Ctx) error {
    var rooms []entities.Room

    res := database.Database.Find(&rooms)
    
    if res.RowsAffected != 0 {
        return c.JSON(fiber.Map{"rooms": rooms})
    } else {
        return c.JSON(fiber.Map{"rooms": nil})
    }
}

My database code: - (hosted at planetscale)

var Database *gorm.DB

func ConnectDb() {
    dsn := "sample_dsn/mydatabase?tls=true&interpolateParams=true"
    db, err := gorm.Open(mysql.Open(dsn))
    if err != nil {
        panic("Failed to connect to DB")
    }
    // Setup Migrations Here
    db.AutoMigrate(&entities.Booking{})
    db.AutoMigrate(&entities.Inventory{})
    db.AutoMigrate(&entities.Room{})
    db.AutoMigrate(&entities.User{})
    Database = db
}

Console output: -

{{1 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} }
{{2 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} }
{{3 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} }
{{4 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} }

Data in database:-

id       created_at              updated_at          deleted_at      **room_type**
1   2024-01-18 19:27:36.680   2024-01-18 19:27:36.680                 DOUBLE_ROOM
2   2024-01-18 19:27:41.206   2024-01-18 19:27:41.206                 DOUBLE_ROOM
3   2024-01-18 19:27:49.403   2024-01-18 19:27:49.403                 KING_SIZE_AC
4   2024-01-19 11:06:11.789   2024-01-19 11:06:11.789                 DOUBLE_BED

API output: -

{
  "rooms": [
    {
      "ID": 1,
      "CreatedAt": "0001-01-01T00:00:00Z",
      "UpdatedAt": "0001-01-01T00:00:00Z",
      "DeletedAt": null,
      "room_type": ""
    },
    {
      "ID": 2,
      "CreatedAt": "0001-01-01T00:00:00Z",
      "UpdatedAt": "0001-01-01T00:00:00Z",
      "DeletedAt": null,
      "room_type": ""
    },
    {
      "ID": 3,
      "CreatedAt": "0001-01-01T00:00:00Z",
      "UpdatedAt": "0001-01-01T00:00:00Z",
      "DeletedAt": null,
      "room_type": ""
    },
    {
      "ID": 4,
      "CreatedAt": "0001-01-01T00:00:00Z",
      "UpdatedAt": "0001-01-01T00:00:00Z",
      "DeletedAt": null,
      "room_type": ""
    }
  ]
}

Update:- 01/20/2024

This exact code works when I switch to a Postgres database. So I switched to Postgres and closed this ticket.

Solution

I did a quick test using the following code:

package main

import (
    "github.com/gofiber/fiber/v2"
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
    "log"
)

var (
    dsn = "host=localhost user=postgres password=secret dbname=mySampleDb port=5432 sslmode=disable"
)

type Room struct {
    gorm.Model
    RoomType string `json:"room_type" validate:"required"`
}

var DB *gorm.DB

func main() {
    initDb()
    app := fiber.New()

    app.Get("/", getAllRoomsForFiber)

    app.Listen(":3000")
}
func getAllRoomsForFiber(c *fiber.Ctx) error {
    var rooms []Room
    res := DB.Find(&rooms)
    if res.RowsAffected != 0 {
        return c.JSON(fiber.Map{"rooms": rooms})
    } else {
        return c.JSON(fiber.Map{"rooms": nil})
    }
}

func seedDb() {
    DB.Create(&Room{RoomType: "single"})
    DB.Create(&Room{RoomType: "Deluxe bed"})
    DB.Create(&Room{RoomType: "Twin bed"})
    DB.Create(&Room{RoomType: "King Size bed"})
}
func initDb() {
    db, err := gorm.Open(postgres.Open(dsn))
    if err != nil {
        log.Fatal("couldn't connect to db")
    }
    DB = db
    db.AutoMigrate(&Room{})
    seedDb()
}

This is what I got:

Deba4139f5302207be648f12c74de60e

The above is the detailed content of GORM Find(&room) operation fills structure with empty data instead of actual data. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete