AndreaM16
AndreaM16

Reputation: 3985

Unable to set foreign key using gorm Postgresql

I'm building a Golang backend using jinzhu/gorm and I'm having some troubles trying to set up a relation between two tables e.g. Items and Manufacturers using a foreign key.

I'm following the steps at jinzhu.me/gorm/models but I'm honestly finding myself puzzled coming from a more straightforward approach of manually writing tables etc, for instance, using go pq.

item.go:

package model

import "github.com/jinzhu/gorm"

type Item struct {
    gorm.Model
    Item         string       `gorm:"primary_key"`
    Manufacturer Manufacturer `gorm:"ForeignKey:Name"`
}

manufacturer.go:

package model

import "github.com/jinzhu/gorm"

type Manufacturer struct {
    gorm.Model
    Name string `gorm:"primary_key"`
}

I get no errors nor warnings. Inspecting my tables I noticed no correlation was created. Item does not have Manufacturer field.

What I tried so far:

EDIT:

Trying something like

type Item struct {
    Item             string       `gorm:"primary_key"`
    Manufacturer     Manufacturer
    ManufacturerID   int
}

type Manufacturer struct {
    ID uint
    Name string
}

Leads to the same result. No foreign key is created and I'm able to insert new items with a non-existent Manufacturer.

What Am I doing wrong? Am I missing something?

Upvotes: 3

Views: 10062

Answers (3)

Bilal Koçoğlu
Bilal Koçoğlu

Reputation: 47

Try this please

    type Item struct {
        Item             string       `gorm:"primary_key"`
        Manufacturer     Manufacturer `gorm:"foreignKey:ManufacturerID;references:id"`
        ManufacturerID   int
    }
    
    type Manufacturer struct {
        ID uint
        Name string
    }

    DB.AutoMigrate(&Item{},&Manufacturer{})

    item := Item{
        Item:         "item",
        Manufacturer: Manufacturer{
            Name:     "name"
        },
    }
    
    DB.Create(&item)

Upvotes: 2

Mike Sallese
Mike Sallese

Reputation: 827

I couldn't get any of the solutions I found working for this while following gorm's documentation / googling / stack overflow. Here's what worked for me:

I have a Call object & TranscriptItem object.

A call can have many transcript items but a transcript item can only have one call.

Call object

type Call struct {
    gorm.Model
    DialInNumber      string
}

Transcript object

type TranscriptItem struct {
    gorm.Model
    Transcript string
    CallID     uint
}

I have my auto migration and a manual AddForeignKey migration

    db.AutoMigrate(&Call{}, &TranscriptItem{})
    db.Model(&TranscriptItem{}).AddForeignKey("call_id", "calls(id)", "RESTRICT", "RESTRICT")

I would've preferred to use the mechanics outlined in gorm's documentation, but at the end of the day I just needed something that worked.

Upvotes: 1

dave
dave

Reputation: 64705

You have to do something like:

type Item struct {
    gorm.Model
    Item         string       `gorm:"primary_key"`
    ManufacturerName string   `sql:"type:varchar REFERENCES manufacturers(name)"`
    Manufacturer Manufacturer `gorm:"ForeignKey:ManufacturerName;AssociationForeignKey:Name`
}

To tell it to a) Use ManufacturerName as the foreign key, and B) use Name on the other table.

Or you can just do:

type Item struct {
    gorm.Model
    Item         string       `gorm:"primary_key"`
    ManufacturerID uint       `sql:"type:uint REFERENCES manufacturers(id)"`
    Manufacturer Manufacturer `gorm:"ForeignKey:Man;AssociationForeignKey:Name"`
}

Upvotes: 3

Related Questions