Search code examples
mysqldatabasegomany-to-manygo-gorm

How can I create a recursive association using GORM?


Question: How can I create a recursive association using GORM?

Context: I have an equipment that can be define manually as well as automatically. I want to associate a manual equipment with the automatically defined one. So I decided to create a table for this many2many association.

CREATE TABLE `equipment` (
  `equipment_id` int(11) NOT NULL,
  `manage_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `equipment`
  ADD PRIMARY KEY (`equipment_id`),
  ADD UNIQUE KEY `unique_equipment` (`model_id`,`manage_ip`);

CREATE TABLE `manual_auto` (
  `manual_id` int(11) NOT NULL,
  `auto_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `manual_auto`
  ADD PRIMARY KEY (`manual_id`,`auto_id`),
  ADD KEY `FK_AUTO` (`auto_id`);

ALTER TABLE `manual_auto`
  ADD CONSTRAINT `FK_AUTO` FOREIGN KEY (`auto_id`) REFERENCES `equipment` (`equipment_id`),
  ADD CONSTRAINT `FK_MANUAL` FOREIGN KEY (`manual_id`) REFERENCES `equipment` (`equipment_id`);

I know that I can create a many2many association table using gorm:"many2many:manual_auto". More info on associations with GORM: http://jinzhu.me/gorm/associations.html#belongs-to

type Equipment struct {
    ID        uint
    Ip        string
    Equipment Equipment `gorm:"many2many:manual_auto"`
}

Thank you in advance.

Edit: More information about the context

I want to have two version of an equipment, one will be created automaticity by fetching another database. Then if any user make a modification about the description of the equipment I want to have 2 version of this equipment, "manual_equipement" and "automatic_equipment".


Solution

  • When it's "many", then you need an array/slice:

    type Equipment struct {
        ID        uint
        Ip        string
        Equipment []Equipment `gorm:"many2many:manual_auto"`
    }
    

    also names of your manually created schema does not match names from struct. Or you can use db.AutoMigrate or define column names in gorm tags:

    type Equipment struct {
        ID        uint        `gorm:"column:equipment_id"`
        Ip        string      `gorm:"column:manage_ip"`
        Equipment []Equipment `gorm:"many2many:manual_auto"`
    }