Max Feinberg
Max Feinberg

Reputation: 840

How to properly use Gorm auto increment?

I have a Go struct that defines a table managed by gorm. It includes a unique, integer, primary key that auto increments.

type CreatedSurvey struct {
    ...
    Id int `json:"id" gorm:"primaryKey;autoIncrement:true;unique"`
    ...
}

Every CreatedSurvey object has its own unique Id and it is created from a template which has its own unique template Id (SurveyTemplateId) field that can be used to trace the created object back to its template. When the front-end application calls an API endpoint that triggers the creation of a new CreatedSurvey, it provides all of the information from the template, including this template SurveyTemplateId. And initially, this SurveytemplateId was marshalled to the CreatedSurvey Id field. For an Id of 0, this caused no issues when MyDb.DB.Create(&survey) is called, the autoIncrement functions properly. However, if the provided Id field is > 0, autoIncrement doesn't take place, and because of the primary key nature of the attribute, a conflict can cause errors.

To avoid this issue, I have been setting the value of the Id to 0 explicitly after the JSON has been marshalled.

    var createdSurvey surveys.CreatedSurvey
    err := ctx.ShouldBindJSON(&createdSurvey)
    if err != nil {
        restErr := errors.NewBadRequestError("invalid json body")
        ctx.JSON(restErr.Status, restErr)
        return
    }
    createdSurvey.Id = 0

This avoids any issues on creation.

result := users_db.DB.Create(&survey)

This works, but it doesn't look clean and doesn't seem to fit in with the general cleanliness of Go.

Should I be using gorm differently? Or is this the best option?

Upvotes: 1

Views: 10571

Answers (3)

David Abgaryan
David Abgaryan

Reputation: 41

    type User struct {
    gorm.Model
    Id        uint      `json:"id" gorm:"unique;primaryKey;autoIncrement"`
    Name      string    `json:"name"`
    Username  string    `json:"username" gorm:"unique"`
    Email     string    `json:"email" gorm:"unique"`
    Password  string    `json:"password"`
    CreatedAt time.Time `json:"createdAt" `
}

Upvotes: 2

jexroid
jexroid

Reputation: 296

There is a convenient solution available that can seamlessly handle various types of databases, including postgres and mysql, without requiring manual intervention. This solution ensures that the form effectively manages all database interactions automatically.There's a simpler solution which it doesn't matter what database you're using such as postgres,mysql and Form will manage them automatically:

as GORM docs sayed, If you use gorm.Model it will automatically handle these fields for you:

  ID           uint           // Standard field for the primary key
  CreatedAt    time.Time      // Automatically managed by GORM for creation time
  UpdatedAt    time.Time      // Automatically managed by GORM for update time
  DeletedAt    gorm.DeletedAt // Automatically managed by GORM for deletion time

if you use the gorm.Model like the code below:

type User struct {
    gorm.Model
    firstname string
    lastname  string
    phone     string `gorm:"unique"`
    password  string
}

gorm will automatically handle the ID, CreatedAt, UpdatedAt, DeletedAt fields in whatever database you have. there's no need for you to increment anything.

enter image description here

you can read more in this link

Upvotes: 1

joseph
joseph

Reputation: 180

Try this:

type CreatedSurvey struct {
...
Id uint64 `json:"id" sql:"AUTO_INCREMENT" gorm:"primary_key"`
...
}

Upvotes: 1

Related Questions