Home > Blockchain >  GORM foreign key doesn't seem to add proper fields
GORM foreign key doesn't seem to add proper fields

Time:10-06

I have the following model:

type Drink struct {
    gorm.Model           // Adds some metadata fields to the table
    ID         uuid.UUID `gorm:"type:uuid;primary key"`
    Name       string    `gorm:"index;not null;"`
    Volume     float64   `gorm:"not null;type:decimal(10,2)"`
    ABV        float64   `gorm:"not null;type:decimal(10,2);"`
    Price      float64   `gorm:"not null;type:decimal(10,2);"`
    Location   Location  `gorm:"ForeignKey:DrinkID;"`
}

type Location struct {
    gorm.Model           // Adds some metadata fields to the table
    ID         uuid.UUID `gorm:"primary key;type:uuid"`
    DrinkID    uuid.UUID
    Name       string `gorm:"not null;"`
    Address    string `gorm:"not null;type:decimal(10,2)"`
    Phone      int    `gorm:"not null;type:decimal(10,0);"`
}

however, when I run the program, it adds both tables, however there is no location field in the Drink table. My database looks like this after the migrations, regardless of whether I drop the tables previously: database after migration

I have a sneaking feeling it might be because I am not using the gorm default ID, but if that's the case can anyone point me to how to override the default ID with a UUID instead of a uint the proper way? or if that's not even the issue, please, I've been working on this for a few days now and I really don't want to take the "easy" road of just using the defaults gorm provides, I actually want to understand what is going on here and how to properly do what I am trying to do. I am getting no errors when running the API, and the migration appears to run as well, it's just the fields I have defined are not actually showing up in the database, which means that the frontend won't be able to add data properly.

What I WANT to happen here is that a list of stores will be available in the front-end, and when a user adds a drink, they will have to select from that list of stores. Each drink added should only have 1 store, as the drinks prices at different stores would be different. So technically there would be many "repeated" drinks in the drink table, but connected to different Locations.

CodePudding user response:

  • First point is as you are using custom primary key, you should not use gorm.Model as it contains ID field in it. Reference
  • Second point is according to your description, store (location) has one to many relationship with drink. That means a store can have multiple drinks but a drink should belong to only one store. In one-to-many relationship there should be a reference or relation id in the many side. That means in your case in drink table. Then your struct should look like this:

MyModel Struct

type MyModel struct {
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt gorm.DeletedAt `gorm:"index"`
}

Location Struct (Store)

type Location struct {
    MyModel
    ID         uuid.UUID `gorm:"primary key;type:uuid"`
    // other columns...
    Drinks     []Drink 
}

Drink Struct

type Drink struct {
    MyModel
    ID         uuid.UUID `gorm:"type:uuid;primary key"`
    //other columns...
    LocationID   uuid.UUID// This is important
}

Then gorm will automatically consider LocationID in drink table will be referring the ID field of Location Table. You can also explicitly instruct this to gorm using gorm:"foreignKey:LocationID;references:ID" in Location struct's Drinks array field.

Reference

  • Related