如何在gorm中对相关数据进行分页?

How to paginate related data in gorm?

我正在创建一个允许用户 post 引用书籍的应用程序。用户可以将其他用户post编辑的名言添加到他们的收藏夹。

这是我的数据模型。

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

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" validate:"required,min=1,max=400"`
    Page          int       `json:"page" validate:"gte=0,lte=50560"`
    Published     bool      `gorm:"default:false" json:"published"`
    Book          Book      `json:"book" validate:"required"`
    Tags          []Tag     `gorm:"many2many:quotes_tags;" json:"tags" validate:"required"`
    BookID        int       `json:"book_id"`
    User          User      `json:"user"`
    UserID        string    `json:"user_id"`
    FavoriteUsers []User    `gorm:"many2many:users_quotes;" json:"favorite_users"`
}


我想通过指定限制和偏移量来检索用户已添加到收藏夹的报价。

func (service *Service) GetUserById(uid string) (models.User, error) {
    user := models.User{}
    if result := service.db.
        Preload("FavoriteQuotes.Tags").
        Preload("FavoriteQuotes.Book").
        Preload("FavoriteQuotes.User").
        Preload("Quotes", "published IS true").
        Preload("Quotes.Book").
        Preload("Quotes.Tags").
        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.GetUserById(uid)
    if err != nil {
        return []models.Quote{}, err
    }
    return user.FavoriteQuotes, nil
}

我目前是这样获取最喜欢的名言的,但我不知道如何实现分页。是否可以使用 gorm 查询来实现?

当然,您可以使用 Custom Preloading SQL。基本上,您传递一个 returns 自定义查询的函数,例如:

Preload("FavoriteQuotes", func(db *gorm.DB) *gorm.DB {
   return db.Offset(0).Limit(10)
})