I have database structure:
type User struct {
db.Base
Username string `gorm:"unique;not null" json:"username"`
Password string `gorm:"not null" json:"password"`
FullName string `gorm:"not null" json:"full_name"`
Email string `gorm:"unique;not null" json:"email"`
}
And Account DB structure:
type Account struct {
db.Base
UserID uuid.UUID `gorm:"not null" json:"user_id"`
User user.User `gorm:"foreignKey:UserID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"user"`
Name string `gorm:"not null" json:"name"`
Currency string `gorm:"not null" json:"currency"`
}
The Base looks like:
type Base struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt *time.Time `sql:"index" json:"deleted_at"`
}
func (base *Base) BeforeCreate(db *gorm.DB) error {
v4 := uuid.NewV4()
db.Set("ID", v4)
base.ID = v4
return nil
}
But when i tried to insert new value:
func Add(u *user.User) (account Account, err error) {
account = Account{
User: *u,
UserID: u.ID,
Currency: currency.EUR.String(),
Name: "Default",
}
err = consts.DB.Model(&Account{}).Save(&account).Error
return account, err
}
The error drops:
ERROR: insert or update on table "accounts" violates foreign key constraint "fk_accounts_user" (SQLSTATE 23503)
[9992.860ms] [rows:0] INSERT INTO "accounts" ("created_at","updated_at","deleted_at","user_id","name","currency","id") VALUES ('2023-01-30 14:55:20.261','2023-01-30 14:55:20.261',NULL,'f5e6984d-4945-4a90-9085-4d6b9d94a8c8','Default','EUR','74943fc5-d767-4e52-8044-d0e9e26e4568') RETURNING "id"
[GIN] 2023/01/30 - 14:55:21 | 400 | 4m56s | ::1 | POST "/api/v1/accounts"
In every request the reference uuid is different. On 27 of the Add function the Id and User is correct. But after saving attempt - UserID is random UUID.
The problem was in method BeforeCreate:
func (base *Base) BeforeCreate(db *gorm.DB) error {
v4 := uuid.NewV4()
db.Set("ID", v4)
base.ID = v4
return nil
}
It generated a new ID for each entity each time a record was created, and along with it, new IDs for all references How to fix? In the Base class, add an ID field of type UUD tag default:
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid();" json:"id"`
Here gen_random_uuid() is internal PostgreSQL method available from, v14 (not sure)