【问题标题】:GORM AutoMigrate Has One & Has Many:GORM 自动迁移 Hasone 和 Hasmany:
【发布时间】:2021-05-28 20:22:04
【问题描述】:

我想创建一个模型UserSocial,其中User 模型有很多Socials。理想情况下,Social 类型也有一个关系来简化从任一侧的查询。这是一个代码示例:

数据库类型是 MySQL 8.0

type base struct {
    ID         string    `json:"id" gorm:"type:char(36);primaryKey;"`
    Created    time.Time `json:"created" gorm:"autoCreateTime"`
    Updated    time.Time `json:"updated" gorm:"autoUpdateTime"`
}

type User struct {
    base
    Friends []*User      `json:"friends" gorm:"many2many:friends"`
    Socials []*Social    `json:"socials"`
}

type Social struct {
    base
    Provider   string `json:"provider" gorm:"type:varchar(32);index"`
    Identifier string `json:"identifier" gorm:"type:varchar(32);index"`
    User      *User   `json:"user" gorm:"foreignKey:ID"`
    Token      string `json:"token"`
    Link       string `json:"link" gorm:"type:varchar(128)"`
}

使用db.AutoMigrate(&User{}, &Social{})时出现以下错误:

model.Social's field User, need to define a valid foreign key for relations or it need to implement the Valuer/Scanner interface
runtime error: invalid memory address or nil pointer dereference

我试过了:

  • gorm:"foreignKey:ID" 添加到 User.Socials 标签
  • 不使用指针(例如在User struct Socials []Social 而不是Socials []*Social

问题依旧

【问题讨论】:

    标签: go go-gorm


    【解决方案1】:

    根据文档 (https://gorm.io/docs/has_many.html#Has-Many), 你需要使用对象,而不是引用

    
    type User struct {
        base
        Friends []User      `json:"friends" gorm:"many2many:friends"`
        Socials []Social    `json:"socials"`
    }
    

    这里没有*

    您也可以将UserID 字段添加到Social

    type Social struct {
        base
        UserID string
        Provider   string `json:"provider" gorm:"type:varchar(32);index"`
        Identifier string `json:"identifier" gorm:"type:varchar(32);index"`
        User      *User   `json:"user" gorm:"foreignKey:ID"`
        Token      string `json:"token"`
        Link       string `json:"link" gorm:"type:varchar(128)"`
    }
    

    并添加

    
    type User struct {
        base
        FriendOf string      `gorm:""`
        Friends []*User      `json:"friends" gorm:"many2many:friends,foreignKey:FriendOf"`
        Socials []*Social    `json:"socials"`
    }
    
    

    【讨论】:

    • 是的,这就是我所说的“我尝试过不使用指针(例如,在User struct Socials []Social 而不是Socials []*Social)”你对自引用many2many 的使用可能不正确。在文档中,他们确实在那里使用了指针。 gorm:"foreignKey:ID" 会不会有问题,关键是不会被称为 ID 吗?
    • 感谢您的帮助,问题出在其他地方,但您的代码块帮助我解决了后续问题。
    • 我在文档中没有看到任何地方说不能使用用户指针。当然,这些示例使用值,但这并不意味着它不适用于指针。
    【解决方案2】:

    问题在这里:

    type base struct {
        ...
    }
    
    type User {
        base
        ...
    }
    
    type Social {
        base
        ...
    }
    

    因为我认为base 只是包本地定义,所以我搞砸了大写并有一个私有主键。

    @vodolaz095 提到了另一个问题,但 (imo) 没有为任何新的go-gorm 用户充分澄清。

    似乎不可能使用像User User 这样的has one 关系作为has manySocials []Social gorm:"foreignKey:User" 这样的关系的外键。需要拆分为@vodolaz095 显示在他的第二个代码块中

    【讨论】:

    • 是的,User struct 永远不能用作外键,因为外键是表上的列,它不能表示为 struct。
    • 这里的关键见解是,您想要的是 Belongs To 和 Has Many 的组合:一个用户有很多社交,一个社交属于一个用户。实现 Has Many 的要求是:User 有一个 Socials,Social 有一个外键 UserID。 Belongs To 的要求是: Social 有一个 User 字段和一个外键 UserID。因此,Social 中的 UserID 与两种模式重叠,但它有效。
    猜你喜欢
    • 2021-10-28
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 2017-02-18
    • 2018-12-06
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多