How to remove RETURNING clause in the Create method of gorm package?

Viewed 878

I got a little confused with the default behavior when creating a record for the gorm package.

city := models.City

if err := databases.DBGORM.Set("gorm:insert_option", "RETURNING *").Create(&city).Error; err != nil {
    fmt.Println(err.Error())
}

In logs I see such SQL query:

INSERT INTO "my_scheme"."city" ("created_at","updated_at","deleted_at","name","country") VALUES ('2020-05-19 23:45:18','2020-05-19 23:45:18',NULL,'New York','USA') RETURNING * RETURNING "my_scheme"."city"."id"

As you can see from the query I have a double RETURNING clause which is not correct and raise an error.

Adding an id at the end of an SQL query seems to be the default behavior of the Create method. How can I change this behavior?

models.go:

package models

import (
    "my_app/proto"
    "time"
)

type City struct {
    Id uint64
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt *time.Time
    proto.City
}

func (City) TableName() string {
    return "my_scheme.city"
}
1 Answers

No, there is no way to change this behavior.

But if you want to get ID or timestamps (CreatedAt and UpdatedAt) after calling Create function, they will be automatically updated in your model passed by pointer.

If you have another field with a default value, add the default tag to this field in the model. And gorm will automatically update that field too after calling Create.

type City struct {
    Id        uint64
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt *time.Time

    SomeField *string `gorm:"default:test"`
}

// ...

city := models.City{}

if err := databases.DBGORM.Create(&city).Error; err != nil {
    fmt.Println(err.Error())
}

fmt.Printf("%+v", city)

[2021-04-13 21:39:44]  [1.06ms]  INSERT INTO "cities" ("created_at","updated_at","deleted_at") VALUES ('2021-04-13 21:39:44','2021-04-13 21:39:44',NULL) RETURNING "cities"."id"  
[1 rows affected or returned ] 

[2021-04-13 21:39:44]  [0.59ms]  SELECT "some_field" FROM "cities"  WHERE (id = 26)  
[1 rows affected or returned ] 

{
  "Id": 26,
  "CreatedAt": "2021-04-13T21:39:44.809605473+07:00",
  "UpdatedAt": "2021-04-13T21:39:44.809605473+07:00",
  "DeletedAt": null,
  "SomeField": "test"
}

If you don't want to update the model at all, pass it to the Create method by value, not a pointer, and ignore the gorm.ErrUnaddressable error.

Related