Using gorm v2.
The models
type Organization struct {
ID uint `gorm:"column:id;primaryKey"`
Name string `gorm:"column:name"`
Code string `gorm:"column:code"`
Users []*User `gorm:"many2many:user_organizations;"`
Licenses []*License `gorm:"foreignKey:organization_id"`
gorm.Model
}
type User struct {
ID uint `gorm:"column:id;primaryKey"`
Name string `gorm:"column:name"`
Token string `gorm:"column:token"`
Admin bool `gorm:"column:admin"`
Organizations []*Organization `gorm:"many2many:user_organizations;"`
Email string `gorm:"column:email;unique"`
Password []byte `gorm:"column:password" json:"-"`
Licenses []*License `gorm:"many2many:user_licenses;"`
gorm.Model
}
type License struct {
ID uint `gorm:"column:id;primaryKey"`
Endpoint string `gorm:"column:endpoint"`
ServiceName string `gorm:"column:service_name"`
Expiry string `gorm:"column:expiry"`
CurrentUser int `gorm:"column:current_user"`
OrganizationID uint `gorm:"column:organization_id;foreignKey:ID;default:null"`
PaymentDue int `gorm:"column:payment_due"`
LastActive time.Time `gorm:"column:last_active"`
Users []*User `gorm:"many2many:user_licenses;"`
gorm.Model
}
Inserting test data:
func test() {
dsn := "host=localhost user=postgres password=postgres dbname=auth port=6789 sslmode=disable"
AuthDB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
fmt.Println("Failed to connect to Auth db")
}
AuthDB.AutoMigrate(&Organization{})
AuthDB.AutoMigrate(&User{})
AuthDB.AutoMigrate(&License{})
password, _ := bcrypt.GenerateFromPassword([]byte("test"), 12)
org := Organization{Name: "TestOrg"}
user := User{Name: "Admin", Email: "test", Password: password, Admin: true}
licenses := []*License{{Endpoint: "/python-test/", ServiceName: "generic-webservice1"},
{Endpoint: "/generic-react1/", ServiceName: "generic-react1"}}
AuthDB.Create(&org)
AuthDB.Create(&user)
AuthDB.Create(&licenses)
// ONE TO MANY tests
// This works for updating licenses
for _, license := range licenses {
license.OrganizationID = org.ID
AuthDB.Save(&license)
}
// This does not work. Don't understand why.
org.Licenses = licenses
AuthDB.Session(&gorm.Session{FullSaveAssociations: true}).Updates(&org)
// This does not work. Don't understand why.
AuthDB.Model(&org).Association("Licenses").Append(licenses)
// MANY TO MANY tests
// This does not work.
user.Licenses = licenses
AuthDB.Session(&gorm.Session{FullSaveAssociations: true}).Updates(&user)
// This does not work.
AuthDB.Model(&user).Association("Licenses").Append(licenses)
// Lets try many to many without array
// Does not work
user.Organizations = append(user.Organizations, &org)
AuthDB.Session(&gorm.Session{FullSaveAssociations: true}).Updates(&user)
// Does not work.
AuthDB.Model(user).Association("Licenses").Append(&org)
}
Error: "WHERE conditions required"
Resources For appending relationships. https://gorm.io/docs/associations.html
db.Model(&user).Association("Languages").Append([]Language{languageZH, languageEN}) db.Session(&gorm.Session{FullSaveAssociations: true}).Updates(&user)
I cannot get this working. I know the solution is obvious and there are plenty of questions like this. If I can get just one example working method for many2many I will be very grateful.
Expected answer
The many2many table should be updated.
Comment From: C-monC
I have fixed the issue after several hours.
Removing gorm.Model from the models made every method just work.
The clue was in the error Error: "WHERE conditions required". I think gorm tries to update the last_updated time with no id.