DEV Community

ADITYA OKKE SUGIARSO
ADITYA OKKE SUGIARSO

Posted on

Define a Self-Referential Many-to-Many Model in GORM

#go

stack:

  • Language: Go
  • ORM: GORM

ref:

case:

  • Self-referential table
  • Association type: many-to-many
  • Join table has additional columns beyond the two foreign keys

step:

  1. Define Item
type Item struct {
    ID         string `gorm:"primaryKey; type:VARCHAR(36); NOT NULL"`
    Name       string `gorm:"type:VARCHAR(100); NOT NULL"`
    Price      int32  `gorm:"type:INT; NOT NULL"`
    ChildItems []Item `gorm:"many2many:parent_child_items;foreignKey:ID;joinForeignKey:ParentID;References:ID;joinReferences:ChildID"`
}
Enter fullscreen mode Exit fullscreen mode

Which creates join table: parent_child_items

  • foreign key: parent_id, reference: items.id
  • foreign key: client_id, reference: items.id
  1. Define ParentChildItem
type ParentChildItem struct {
    ParentID string `gorm:"primaryKey; type:VARCHAR(36); NOT NULL"`
    ChildID  string `gorm:"primaryKey; type:VARCHAR(36); NOT NULL"`
    CreatedAt time.Time
    DeletedAt gorm.DeletedAt
}
Enter fullscreen mode Exit fullscreen mode

We define this because the parent_child_items table stores more than just parent_id and child_id. It’s a custom association table with extra fields (CreatedAt, DeletedAt), not a pure join table.

  1. Run this code on startup
    db.AutoMigrate(&entity.Item{}, &entity.ParentChildItem{})
    err := db.SetupJoinTable(&entity.Item{}, "ChildItems", &entity.ParentChildItem{})
    if err != nil {
        panic(fmt.Sprintf("Failed to setup join table: %v", err))
    }
Enter fullscreen mode Exit fullscreen mode

Top comments (0)