使用 gorm 插入 table 时外键约束失败

A foreign key constraint fails when insert to table with gorm

当我尝试插入具有一对多关系的 gorm 的 table 时,出现此错误:

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)....

这些是我的模型:

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
}

这是我写的函数:

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
}

我正在使用 MariaDB。

TodoList 缺少引用关键字。应该是这样的。

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"`
}

它需要来自 gorm 结果的 user。改变你的方法可能是这样的:

// 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})
}