Your Question

Is it possible to specify ON DELETE and ON UPDATE for the foreign keys of a many2many relationship?

I tried the following, but it didn't add the ON DELETE part when creating the table:

type User struct {
   // ...
   Albums []Album `gorm:"many2many:user_albums;constraint:OnDelete:CASCADE;"`
}

I would like a structure where whenever a User or an Album is deleted, any related user_albums entries should automatically be deleted as well.

The document you expected this should be explained

The documentation touches on this Many to many - foreign key constraints, but the example seems uncomplete or invalid.

It says "You can setup OnUpdate, OnDelete constraints with tag constraint, [...] for example:". And is then followed by a code example that doesn't use the constraint tag at all. Am I missing something?

Expected answer

I expected the example in the documentation to clearly show how the constraint tag is used for many2many relations.

Comment From: jinzhu

https://gorm.io/docs/many_to_many.html#Customize-JoinTable

Comment From: simon-widlund

@jinzhu The possibility to get the same result another way doesn't make the documentation error disappear. This should be fixed rather than closing the issue.

I was also confused by this documentation. In my case, I did get it working through trial and error, using the constraint:OnDelete:CASCADE tag like this:

type Accessory struct {
    AccessoryProperties
    Id                  string   `gorm:"primaryKey;size:256"`
    Branches            []Branch `gorm:"many2many:accessory_branches"`
}

type Branch struct {
    Id          string      `gorm:"primaryKey;size:256;constraint:OnDelete:CASCADE"`
    Accessories []Accessory `gorm:"many2many:accessory_branches;constraint:OnDelete:CASCADE"`
}

Comment From: myhendry

I open an issue on Stackoverflow. I can't achieve a cascade delete on One-to-Many & Belongs-To association

https://stackoverflow.com/questions/67749708/cascade-delete-in-gorm-does-not-remove-associated-tables

Comment From: DehaiWang

type User struct { // ...

Albums []Album }

HasMany Association Mode : db.Model(&item).Select("Albums ").Delete(item) it works.

Comment From: ngocketit

@jinzhu The possibility to get the same result another way doesn't make the documentation error disappear. This should be fixed rather than closing the issue.

I was also confused by this documentation. In my case, I did get it working through trial and error, using the constraint:OnDelete:CASCADE tag like this:

``go type Accessory struct { AccessoryProperties Id stringgorm:"primaryKey;size:256"Branches []Branchgorm:"many2many:accessory_branches"` }

type Branch struct { Id string gorm:"primaryKey;size:256;constraint:OnDelete:CASCADE" Accessories []Accessory gorm:"many2many:accessory_branches;constraint:OnDelete:CASCADE" } ```

This works. However, AutoMigrate doesn't add the constraint when it's added after the model has been defined and looks like the only solution is to drop the table and let AutoMigrate recreate it

Comment From: jinzhu

@jinzhu The possibility to get the same result another way doesn't make the documentation error disappear. This should be fixed rather than closing the issue. I was also confused by this documentation. In my case, I did get it working through trial and error, using the constraint:OnDelete:CASCADE tag like this: ``go type Accessory struct { AccessoryProperties Id stringgorm:"primaryKey;size:256"Branches []Branchgorm:"many2many:accessory_branches"` }

type Branch struct { Id string gorm:"primaryKey;size:256;constraint:OnDelete:CASCADE" Accessories []Accessory gorm:"many2many:accessory_branches;constraint:OnDelete:CASCADE" } ```

This works. However, AutoMigrate doesn't add the constraint when it's added after the model has been defined and looks like the only solution is to drop the table and let AutoMigrate recreate it

https://github.com/go-gorm/gorm/issues/4110

Comment From: pavittarsingh315

As of v1.24.2, adding the constraint directly into the parent struct will work properly. Here is an example:

type Accessory struct {
    AccessoryProperties
    Id                  string   `gorm:"primaryKey;size:256"`
    Branches            []Branch `gorm:"many2many:accessory_branches;constraint:OnDelete:CASCADE;"`
}

Comment From: akhmedmukhtarov

I reach the result by changing sequence of struct tags gorm:"many2many:categories_courses;constraints:OnDelete:CASCADE" ❌, gorm:"constraints:OnDelete:CASCADE;many2many:categories_courses"

type Category struct {
    Model
    Name string 
    Image string 
    Courses []Course `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;many2many:categories_courses"`
}

type Course struct {
    Model
    Name        string     
    Image       string     
    Language    string    
    LessonCount int       
    Description string    
    PriceUzs    int        
    Topics      []Topic    `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
    Categories []Category `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;many2many:categories_courses"`
}