Reputation: 3985
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:
gorm:"ForeignKey:Name"
since Manufacturer
field is already a Manufacturer
gorm:"ForeignKey:Name;AssociationForeignKey:Name"
db.Model(&model.Item{}).Related(&model.Manufacturer{})
db.Model(&model.Item{}).Related(&model.Manufacturer{}, "Manufacturer")
db.Model("items").Related("manufacturers")
. They get created with this name on Postgresql even though their model's name is singular.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
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
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
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