美文网首页
记录下beego 多对多模型查询的吐血经历

记录下beego 多对多模型查询的吐血经历

作者: Mr_dreamer | 来源:发表于2020-03-01 23:42 被阅读0次

    最近写一个博客练手,文章功能需要增加一个标签的功能,一篇文章可以有多个标签,一个标签可以被多个文章使用,于是就想用m2m模型实现,过程如下

    文章模型简化如下:

    type Article struct {
    
        Id          int       `form:"-"`
        //这个是标签
        Label       []*Label  `orm:"rel(m2m);rel_through(blog/models.Articlelabel)"`
    
    }
    

    这里说一下这个rel_through, 官方文档的说法是pkg.models.struct 用点儿连接,但是实际情况不是路径还是要用/ 不知道是不是我对官方文档理解有问题,还是官方的说法有瑕疵

    下面是标签模型:

    type Label struct {
        Id int `form:"-"`
        Title string `form:"title"`
        //这个是文章关联
        Article []*Article `orm:"reverse(many)"`
    }
    

    下面是关联模型

    type Articlelabel struct {
        Id int 
        Article *Article `orm:"rel(fk)"`
        Label *Label `orm:"rel(fk)"`
    }
    

    注意关联模型中的 ArticleLabel 都不能加id 查询会自动加上

    我的列表查询如下

    func ArtList() ([]Article, error) {
        var list []Article
    
        o := orm.NewOrm()
        orm.Debug = true
        _, err := o.QueryTable("article").RelatedSel().Limit(10).All(&list)
        if err != nil {
            return []Article{}, err
        }
            //这个是正确的写法
        /*for k,_ := range list {
            o.LoadRelated(&list[k], "Label")
                
        }*/
          
            //这个是错误的写法
            for _, v := range list {
            o.LoadRelated(v, "Label")       
        }
    
        return list, nil
    }
    

    然后就报错了

    2020/03/01 18:54:29.795 [C] [panic.go:679]  the request url is  /admin/article
    2020/03/01 18:54:29.795 [C] [panic.go:679]  Handler crashed with error <Ormer> cannot use non-ptr model struct `blog/models.Article`
    ...
    

    Article 结构体空指针,于是我查阅了文档,发现 LoadRelated参数都是指针, 下面是文档给的例子

    // 载入相应的 Tags
    post := Post{Id: 1}
    err := o.Read(&post)
    num, err := o.LoadRelated(&post, "Tags")
    

    于是我把我的代码也换成了指针o.LoadRelated(&v, "Label"),发现不报错了,但是也没有查询到。这就奇怪了。于是我想到是不是&v 并不是真的指向了原来的结构体,经过谷歌之后发现还真是这样,for循环的时候 &v指向的其实是 v的地址,而不像PHP一样就是原来的参数引用。那就只能用 list[k]来更改了
    于是

    for k,_ := range list {
            o.LoadRelated(&list[k], "Label")
                
        }
    

    这样就成了,对于查询一条记录同理,只不过不需要循环我的list, 而是直接像官方文档给的例子那样写就可以了

    事后我测试

    a := [] int {1}
        for k,v := range a {
            fmt.Println(&v)
            fmt.Println(&a[k])
        }
    //两个不同的地址
    //0x40e024
    //0x40e020
    
    

    看来我还是基础不过关啊,共勉

    相关文章

      网友评论

          本文标题:记录下beego 多对多模型查询的吐血经历

          本文链接:https://www.haomeiwen.com/subject/nrrdkhtx.html