Home > Back-end >  A foreign key constraint fails when insert to table with gorm
A foreign key constraint fails when insert to table with gorm

Time:03-04

When I try to insert to a table with gorm which has one to many relationship, I get this error:

Error 1452: Cannot add or update a child row: a foreign key constraint fails (`Todo`.`todos`, CONSTRAINT `fk_users_todo_list` FOREIGN KEY (`fk_id`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE CASCADE)....

These are my models:

type Base struct {
    ID        uint `gorm:"primaryKey"`
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt *time.Time `gorm:"index"`
}

type User struct {
    Base
    FirstName string           `form:"first_name" gorm:"type:varchar(20)"`
    LastName  string           `form:"last_name" gorm:"type:varchar(20)"`
    UserName  string           `form:"user_name" gorm:"unique;type:varchar(20)"`
    Email     string           `form:"email" gorm:"type:varchar(100)"`
    Password  string           `form:"password" gorm:"type:varchar(30)"`
    Gender    types.UserGender `form:"gender" gorm:"type:smallint"`
    TodoList  []Todo           `gorm:"foreignKey:FkID;constraint:onDelete:SET NULL,onUpdate:CASCADE" json:"omitempty"`
}

type Todo struct {
    Base
    Name        string
    Description string
    Status      types.TaskStatus
    FkID        uint
}

And this is the function that I wrote:

func (d *DB) AddTODO(todo *models.Todo, userName string) error {
    user := &models.User{UserName: userName}
    err := d.db.Model(&user).Where("user_name = ?", userName).Association("TodoList").
        Append([]models.Todo{*todo})
    if err != nil {
        return err
    }
    return nil
}

I'm using MariaDB.

CodePudding user response:

It want user from gorm result. Change your method maybe like this:

// arg user is from gorm result somewhere
func (d *DB) AddTODO(user *models.User, todo *models.Todo) error {
    return d.db.Model(user).Association("TodoList").Append([]models.Todo{*todo})
}

CodePudding user response:

TodoList lack references keyword. It should be like this.

type User struct {
    Base
    FirstName string           `form:"first_name" gorm:"type:varchar(20)"`
    LastName  string           `form:"last_name" gorm:"type:varchar(20)"`
    UserName  string           `form:"user_name" gorm:"unique;type:varchar(20)"`
    Email     string           `form:"email" gorm:"type:varchar(100)"`
    Password  string           `form:"password" gorm:"type:varchar(30)"`
    Gender    types.UserGender `form:"gender" gorm:"type:smallint"`
    TodoList  []Todo           `gorm:"foreignKey:FkID;references:ID;constraint:onDelete:SET NULL,onUpdate:CASCADE" json:"omitempty"`
}
  • Related