gorm关联查询的坑

背景:最近在学习 golang,尝试将之前的 PHP 项目用 go 改写一下。
涉及的表模型如下三个:

// 文章
type Topics struct {
    Id              int    `gorm:"primary_key"`
    Title           string `gorm:"not null"`
    Body            string `gorm:"not null"`
    UserId          int    `gorm:"not null"`
    CategoryId      int    `gorm:"not null"`
    Status          int    `gorm:"default:1"`
    CreatedAt       time.Time
    UpdatedAt       time.Time
    Category Categories    `gorm:"foreignkey:CategoryId"`
    User     Users         `gorm:"foreignkey:UserId"`
}
// 用户
type Users struct {
    Id                int    `gorm:"primary_key"`
    Name              string `gorm:"not null"`
    Email             string `gorm:"not null"`
    Password          string `gorm:"not null"`
    Avatar            string
    CreatedAt         time.Time
    UpdatedAt         time.Time
    LastActivedAt     time.Time
}
// 分类
type Categories struct {
    Id          int        `gorm:"primary_key"`
    Name        string     `gorm:"not null"`
    Description string     `gorm:"not null"`
    PostCount   int
    CreatedAt   time.Time
    UpdatedAt   time.Time
}

首先找到 gorm 官方文档的相关介绍:
http://doc.gorm.io/associatio…
《gorm关联查询的坑》

跃跃欲试(code V1):

func (Topics) TopicByID(id int) (*Topics, error) {
    db := DB()
    defer db.Close()

    var topic Topics

    // 1. 
    //result := db.Model(&topic).Where("id=?", id).Related(&topic.User)

    //2. 
    //db.Where("id=?", id).First(&topic)
    //result := db.Model(&topic).Related(&topic.User)
    
    if err := result.Error; err != nil {
        return &topic, err
    }

    if result.RecordNotFound() == true {
        return &topic, utils.Error("文章不存在!")
    }

    return &topic, nil
}

代码中的两种形式基本上是我再百度之后找到的结果。尝试了一番,都报错:(invalid association [])。
然后在考虑是否我的外键定义的有问题:

《gorm关联查询的坑》

(也没问题)

继续百度,找到 gorm的关联问题。其中:
《gorm关联查询的坑》

这里 Reload方法加了第二个参数,于是查看gorm关于这个方法的介绍:
《gorm关联查询的坑》

可以加对应的外键参数,测试成功。

最终代码(code V2):

func (Topics) TopicByID(id int) (*Topics, error) {
    db := DB()
    defer db.Close()

    var topic Topics

    db.Where("id=?", id).First(&topic)
    // 关联的关键代码
    db.Model(&topic).Related(&topic.Category, "CategoryId")
    result := db.Model(&topic).Related(&topic.User, "UserId")

    //result := db.Where("id=?", id).Preload("Category").Preload("User").First(&topic)
    if err := result.Error; err != nil {
        return &topic, err
    }

    if result.RecordNotFound() == true {
        return &topic, utils.Error("文章不存在!")
    }

    return &topic, nil
}

注:注释部分的 Preload 方法感觉更加方便简洁。

输出结果: // 包含了文章内容,文章对应用户信息,以及文章分类信息

{
6 测试话题2 <p>who are you?</p> 1 3 0 0 0 0   1 2018-09-11 14:30:39 +0800 CST 2018-09-11 14:43:44 +0800 CST 
{3 问答 请保持友善,互帮互助 0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC} 
{1 aurora test@mail.com 3ffd3de33d3c8bf09bf835d8f7f9b0e0 http://local.beego.com/static/upload/2018/09/07/deepin-cc.png 啦啦啦啦啦~嗝 b506cf029de29c626a1a27bc4d70f5b0 0 2018-08-28 15:56:39 +0800 CST 2018-09-07 14:32:46 +0800 CST 0001-01-01 00:00:00 +0000 UTC}
}

总结:

之前文章的恢复,内容还没来得及整理,将就看下吧

    原文作者:AuroraLZDF
    原文地址: https://segmentfault.com/a/1190000019331511
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞