Search code examples
gomany-to-manygo-gorm

Gorm doesn't create foreignkeys at many to many relationship


I'm having a problem generating my DB using .

  • all of the tables and the relationships (foreign-keys) are generated successfully
  • except for many-to-many relationship.

When I'm building the DB gorm does generate the association table device_group but without foreign-keys.

I have the following structs: Device and Group. A group can have more then 1 device, and the same device can be in more then one Group many-to-many

//Group group of devices
type Group struct {
     gorm.Model
     Name    string
     SVG     string
     Devices []*Device `gorm:"many2many:device_group;"`
     //association_foreignkey:id;foreignkey:id"` 
}

//Device is a singe phisycal mesurment device
type Device struct {
        gorm.Model
        DeviceName string
        Svg        string
        IP         string
        LastActive time.Time
        MAC        string
        Version    string
        Groups     []*Group `gorm:"many2many:device_group;"`
}

Add aforeign key:

db.Model(device).AddForeignKey("id", 
                   "device_group(device_id)", "CASCADE", "CASCADE")

db.Model(group).AddForeignKey("id", 
                   "device_group(group_id)", "CASCADE", "CASCADE")

Running the function AddForeignKey returns this error:

[2020-01-28 11:53:11] pq: there is no unique constraint matching given keys for referenced table "device_group"

As you can see: it's generating the device_group table but there are no foreign keys. I tried to play with field tags, tried to modify the AddForeignKey function or remove it but nothing seems to work.

enter image description here

Any ideas?

thank you


Solution

  • The referenced keys must be primary keys, therefore you have to add the constraints the other way around. The following works for me with your code:

    db.Table("device_group").AddForeignKey("device_id", "devices(id)", "CASCADE", "CASCADE")
    db.Table("device_group").AddForeignKey("group_id", "groups(id)", "CASCADE", "CASCADE")