0
votes

I am developing an application that manages quotes using go and gorm. Users create quote, quotes have multiple tags, and users can add quotes to their favorites.

I want to get a list of quotes that a user has added to their favorites. And at that time, I want to get the tag attached to the quotes.

Here is my data models.

type Quote struct {
    ID            int       `gorm:"primary_key" json:"id"`
    CreatedAt     time.Time `json:"created_at"`
    UpdatedAt     time.Time `json:"updated_at"`
    Text          string    `json:"text"`
    Page          int       `json:"page"`
    Published     bool      `gorm:"default:false" json:"published"`
    Tags          []Tag     `gorm:"many2many:quotes_tags;" json:"tags"`
    User          User      `json:"user"`
    UserID        string    `json:"user_id"`
    FavoriteUsers []User    `gorm:"many2many:users_quotes;" json:"favorite_users"`
}

type User struct {
    ID              string    `json:"id"`
    CreatedAt       time.Time `json:"created_at"`
    UpdatedAt       time.Time `json:"updated_at"`
    Username        string    `json:"username"`
    Quotes          []Quote   `json:"quotes"`
    FavoriteQuotes  []Quote   `gorm:"many2many:users_quotes;" json:"favorite_quotes"`
}

type Tag struct {
    ID        int       `gorm:"primary_key" json:"id"`
    CreatedAt time.Time `json:"created_at"`
    Name      string    `json:"name"`
}

I tried the following and got the favorite quote, but the tags was null. Is there a way to do this with gorm? Thank you in advance.

func (service *Service) GetUser(uid string) (models.User, error) {
    fmt.Println(uid)
    user := models.User{}
    if result := service.db.Preload(clause.Associations).First(&user, "id = ?", uid); result.Error != nil {
        return models.User{}, result.Error
    }
    return user, nil
}

func (service *Service) GetFavoriteQuotes(uid string) ([]models.Quote, error) {
    user, err := service.GetUser(uid)
    if err != nil {
        return []models.Quote{}, err
    }
    return user.FavoriteQuotes, nil
}
1

1 Answers

0
votes

If you check the Preload All documentation, it says:

clause.Associations won’t preload nested associations, but you can use it with Nested Preloading

In your case, this would be something like this:

if result := service.db.Preload("FavoriteQuotes.Tags").Preload(clause.Associations).First(&user, "id = ?", uid); result.Error != nil {
        return models.User{}, result.Error
    }