在相关表中按条件进行GORM预载

时间:2019-01-19 14:02:36

标签: go go-gorm

我不知道如何正确编写查询,该查询将仅选择对关系表应用条件的那些条目。 我的多对多模式如下:Topics-TopicPosts-Posts。我想查询所有TopicPosts不是私有的还是属于当前用户的所有Post。我正在这样做:

topicPosts := []model.TopicPost{}
h.DB.
    Where("topic_id = ?", id).
    Preload("Post", func(db *gorm.DB) *gorm.DB {
        return db.Not("is_private = ? AND user_id != ?", "true", currentUser.ID)
    }).
    Preload("Post.Tags").
    Find(&topicPosts)

如预期的那样,它返回所有TopicPosts,但不急于加载给定条件的Posts。然后,我手动将它们过滤掉:

publicTopicPosts := []model.TopicPost{}
for _, p := range topicPosts {
    if p.Post.ID != 0 {
        publicTopicPosts = append(publicTopicPosts, p)
    }
}

我意识到这是一个低于标准的解决方案,我对SQL不太满意,但我认为应该可以在单个查询中实现。我将不胜感激任何帮助。如果需要的话,我正在使用Postgres。

2 个答案:

答案 0 :(得分:1)

根据我的经验,使用GORM最合适的方法是利用SubQueries:

topicPosts := []model.TopicPost{}   

DB.GetDB().
    Where("topic_id = ? AND post_id IN (?)", id,
        DB.GetDB().Table("posts").
            Select("id").
            Not("is_private = ? AND user_id != ?", "true", currentUser.ID)).
            SubQuery()).

    Preload("Post").
    Find(&topicPosts)

答案 1 :(得分:0)

您可以使用此方法

db.Preload("Post", "is_private = ? AND user_id != ?", "true", currentUser.ID).Find(&topicPosts)