skip to Main Content

In my struct, i have the following

type Task struct {
    gorm.Model
    Id         int       `json:"id" gorm:"primaryKey;AUTO_INCREMENT"`
    UserId int       `json:"user_id" gorm:"Index;not null" validate:"required"`
    TaskId     int       `json:"task_id" gorm:"Index;not null" validate:"required"`
    JobId      int       `json:"job_id" gorm:"not null" validate:"required"`
    Latitude   float64   `json:"latitude" gorm:"not null" validate:"required"`
    Longitude  float64   `json:"longitude" gorm:"not null" validate:"required"`
    StartAt    time.Time `json:"start_at"`
    EndAt      time.Time `json:"end_at"`
    CreatedAt  time.Time
    UpdatedAt  time.Time
}

and i have this function that saves to the table with the following

{   "user_id": 1,
    "location":[5748.5445, 89790.454],
    "latitude": 89790.454,
    "longitude": 5748.5445,
    "startAt":  "2030-10-30T10:58:00.000Z",
    "endAt": "2031-10-30T10:58:00.000Z"
}

func CreateTask(c *fiber.Ctx) error {
    var opentask models.JobOpenTask
    
    if err := c.BodyParser(&opentask); err != nil {
        return c.Status(400).JSON(err.Error())
    }
    
    db.DB.Db.Create(&opentask)
    return c.Status(200).JSON("OK")
}

When this runs, it still saves the record on the DB but I expect it to throw and error when it tries to save since it is not null in my struct but why is it able to save to the Db without throwing an error?

3

Answers


  1. You need to use sql.NullIntxx or int/float pointer for this because default/empty values of int/float is 0, which is not null for database.

    So gorm and DB will allow this to pass through as non null value.

    Similarly for string type where one has to use *string or sql.NullStting as default value of string is "" (blank string) and not nil.

    Login or Signup to reply.
    • First you should check that migrations have been run properly that means not null constraint for user_id, task_id, job_id, .. columns are created in database.
    • Secondly you have to use pointer because golang has a concept of zero value that means int, float, string, bool have default values of 0, 0.0, "", false accordingly, if you doesn’t assign any value. But if you use pointer then this fields will be nil and eventually NULL will be sent in db. And if there is a NOT NULL constraint for that column error will occur.
    Login or Signup to reply.
    • null just apply for pointer
    • gorm.Model include
    type Model struct {
        ID        uint `gorm:"primarykey"`
        CreatedAt time.Time
        UpdatedAt time.Time
        DeletedAt DeletedAt `gorm:"index"`
    }
    

    you don’t need declare Id, CreatedAt, UpdatedAt in your struct

    • Correct your struct as bellow:
    type Task struct {
        gorm.Model
        UserId     int       `json:"user_id"`
        TaskId     int       `json:"task_id"`
        JobId      int       `json:"job_id"`
        Latitude   float64   `json:"latitude"`
        Longitude  float64   `json:"longitude"`
        StartAt    time.Time `json:"start_at"`
        EndAt      time.Time `json:"end_at"`
    }
    
    • And tag and best practice is control by database with column defined not null constraint

    • AUTO_INCREMENT should be create on the database when your create table , this need control by database , not by language

    • declare table as bellow:

    create table tasks (
       int primary key AUTO_INCREMENT,
       user_id int not null, 
       task_id int not null,
       job_id int not null,
       latitude int not null,
       longitude int not null,
       start_at datetime,
       created_at datetime,
       updated_at datetime
    )
    

    wish your study well!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search