here are two models I have and postgres migrations for these two models (every separate migration and struct is in its separate file):
type BaseModel struct {
ID uint64 `gorm:"primarykey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
type User struct {
BaseModel
Password string `gorm:"column:password;size:255;not null"`
Role string `gorm:"column:role;size:255;not null"`
}
type UserContact struct {
BaseModel
User User `gorm:"column:user_id;foreignKey:UserID;references:ID;unique;not null"`
UserID uint64
Address Address `gorm:"column:address_id;foreignKey:AddressID;references:ID;not null"`
AddressID uint64
Email string `gorm:"column:email;size:255;unique;not null"`
Firstname string `gorm:"column:firstname;size:255;not null"`
Lastname string `gorm:"column:lastname;size:255;not null"`
PhoneNumber *string `gorm:"column:phone_number;size:255;unique"`
}
CREATE TABLE "user" (
"id" bigserial PRIMARY KEY,
"password" VARCHAR(255) NOT NULL,
"role" VARCHAR(255) NOT NULL,
"created_at" timestamptz NOT NULL,
"updated_at" timestamptz NOT NULL,
"deleted_at" timestamptz
);
CREATE TABLE "user_contact" (
"id" bigserial PRIMARY KEY,
"user_id" bigserial UNIQUE NOT NULL,
"address_id" bigserial NOT NULL,
"email" VARCHAR(255) UNIQUE NOT NULL,
"firstname" VARCHAR(255) NOT NULL,
"lastname" VARCHAR(255) NOT NULL,
"phone_number" VARCHAR(255) UNIQUE,
"created_at" timestamptz NOT NULL,
"updated_at" timestamptz NOT NULL,
"deleted_at" timestamptz,
CONSTRAINT "fk_user_contact_user_id"
FOREIGN KEY("user_id")
REFERENCES "user"("id"),
CONSTRAINT "fk_user_contact_address_id"
FOREIGN KEY("address_id")
REFERENCES "address"("id")
);
CREATE UNIQUE INDEX idx_user_contact_user_id ON "user_contact"("user_id");
CREATE UNIQUE INDEX idx_user_contact_email ON "user_contact"("email");
CREATE UNIQUE INDEX idx_user_contact_phone_number ON "user_contact"("phone_number");
on this code i have the following error:
func (us *userService) Create(email, password, firstname, lastname string) (*model.User, error) {
encryptedPassword, err := us.hashPassword(password)
if err != nil {
return nil, err
}
user := &model.User{
Password: string(encryptedPassword),
Role: enums.UserRoles.PortalUser().String(),
}
us.db.Create(user)
contact := &model.UserContact{
Email: email,
Firstname: firstname,
Lastname: lastname,
User: *user,
}
us.db.Create(contact)
return user, nil
}
app-1 | 2024/05/14 18:39:46 /app/internatl/pkg/service/user.go:38 cannot convert {{1 2024-05-14 18:39:46.397391868 +0000 UTC 2024-05-14 18:39:46.397391868 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} $2a$08$.LZgf6D1F3VRvK5eNHaO0OuasbZsSvqUUBjy/sPGSO.He55485pfS portal-user} to Int8
it is pointing to line with us.db.Create(contact)
can you help me here? Is it a bug or i'm wrong somewhere?
i tried assigning user.ID
to userContact.UserID
field but that didn't help.
foreign keys (as i see) are set correctly. looks like the issue is GORM can't convert struct to int8 (ID type) because it doesn't see foreignKey:UserID
. wdyt?
I figured out what the issue was.
Instead of
type UserContact struct {
BaseModel
User User `gorm:"column:user_id;foreignKey:UserID;references:ID;unique;not null"`
UserID uint64
Address Address `gorm:"column:address_id;foreignKey:AddressID;references:ID;not null"`
AddressID uint64
Email string `gorm:"column:email;size:255;unique;not null"`
Firstname string `gorm:"column:firstname;size:255;not null"`
Lastname string `gorm:"column:lastname;size:255;not null"`
PhoneNumber *string `gorm:"column:phone_number;size:255;unique"`
}
I should have used this code:
type UserContact struct {
BaseModel
User User `gorm:"foreignKey:UserID;references:ID;unique;not null"`
UserID uint64
Address Address `gorm:"foreignKey:AddressID;references:ID;not null"`
AddressID uint64
Email string `gorm:"column:email;size:255;unique;not null"`
Firstname string `gorm:"column:firstname;size:255;not null"`
Lastname string `gorm:"column:lastname;size:255;not null"`
PhoneNumber *string `gorm:"column:phone_number;size:255;unique"`
}
I hope this topic will help somebody who also decided to put column
tag to gorm tag with foreign key
:)