How can i use proload with scopes to query
victormazeli opened this issue · comments
https://gorm.io/docs/preload.html#Auto-Preloading
How can i use proload with scopes to query ?
i am trying to get gorm preload and scopes to work with find, i am trying to fetch all properties and preload all it images, but it does not work with what i have in my code, but if i do a query to query a single property (using FIRST ) i get the images preloaded. below is the code;
import (
"database/sql"
"encoding/json"
"time"
"gopkg.in/guregu/null.v4"
_ "gopkg.in/guregu/null.v4"
)
type Property struct {
ID uint `json:"id" gorm:"primaryKey"`
PropertyTitle string `json:"property_title" gorm:"type:varchar(255)"`
Description null.String `json:"description" gorm:"type:text"`
Floors null.String `json:"floors" gorm:"type:varchar(255)"`
NumberOfRooms null.String `json:"number_of_rooms" gorm:"type:varchar(255)"`
BedRooms null.String `json:"bed_rooms" gorm:"type:varchar(255)"`
BathRooms null.String `json:"bath_rooms" gorm:"type:varchar(255)"`
CloakRooms null.String `json:"cloak_rooms" gorm:"type:varchar(255)"`
UtilityRooms null.String `json:"utility_rooms" gorm:"type:varchar(255)"`
Conservatory null.String `json:"conservatory" gorm:"type:varchar(255)"`
EntranceHall null.String `json:"entrance_hall" gorm:"type:varchar(255)"`
FrontYard null.String `json:"front_yard" gorm:"type:varchar(255)"`
MudRoom null.String `json:"mud_room" gorm:"type:varchar(255)"`
FurnishedRoom null.String `json:"furnished_room" gorm:"type:varchar(255)"`
Garden null.String `json:"garden" gorm:"type:varchar(255)"`
Garage null.String `json:"garage" gorm:"type:varchar(255)"`
Ensuite null.String `json:"ensuite" gorm:"type:varchar(255)"`
CharacterFeature null.String `json:"character_feature" gorm:"type:text"`
EpcRatings null.String `json:"epc_ratings" gorm:"type:varchar(255)"`
PetsAllowed null.String `json:"pets_allowed" gorm:"type:varchar(255)"`
SmokingAllowed null.String `json:"smoking_allowed" gorm:"type:varchar(255)"`
DssAllowed null.String `json:"dss_allowed" gorm:"type:varchar(255)"`
SharersAllowed null.String `json:"sharers_allowed" gorm:"type:varchar(255)"`
AverageRating null.Float `json:"average_rating" gorm:"type:float"`
Address null.String `json:"address" gorm:"type:text"`
State NullString `json:"state" gorm:"type:text"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
City string `json:"city" gorm:"type:varchar(255)"`
Country string `json:"country" gorm:"type:varchar(255)"`
PostalCode string `json:"postal_code" gorm:"type:varchar(255)"`
PropertyImages []PropertyImage `json:"property_images"`
PropertyType string `json:"property_type"`
PropertyDetachedType string `json:"property_detached_type"`
UserID uint `json:"user_id"`
IsVisible int64 `json:"is_visible" gorm:"default:0"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt null.Time `json:"deleted_at"`
}
type NullString struct {
sql.NullString
}
// MarshalJSON for NullString
func (ns *NullString) MarshalJSON() ([]byte, error) {
if !ns.Valid {
return []byte("null"), nil
}
return json.Marshal(ns.String)
}
type PropertyImage struct {
ID uint `json:"id" gorm:"primaryKey"`
ImageUrl string `json:"image_url" gorm:"type:varchar(255)"`
PropertyID uint `json:"property_id" gorm:"foreignkey:PropertyID"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt null.Time `json:"deleted_at"`
}
package main
import (
"math"
"rateMyRentalBackend/http/response"
"rateMyRentalBackend/models"
"strconv"
"gorm.io/gorm"
)
func Paginate(page int64, limit int64, query map[string]interface{}, sort string) func(db *gorm.DB) *gorm.DB {
offset := (page - 1) * limit
return func(db *gorm.DB) *gorm.DB {
return db.Offset(int(offset)).Limit(int(limit)).Where(query).Order(sort)
}
}
func Pagination(model interface{}, page string, limit string, sort string, query map[string]interface{}, preloadQuery *string, db *gorm.DB) (*response.PaginationDTO, error) {
parsePage, er := strconv.ParseInt(page, 0, 64)
if er != nil {
return nil, er
}
// parse query "limit" to int
parseLimit, e := strconv.ParseInt(limit, 0, 64)
if e != nil {
return nil, e
}
var totalRows int64
// Explicitly set the table name for the model before using it in the query
db.Model(&models.Property{}).Where(query).Count(&totalRows)
totalPages := int(math.Ceil(float64(totalRows)) / float64(parseLimit))
var data []map[string]interface{}
queryDB := db.Model(&models.Property{}).Scopes(Paginate(parsePage, parseLimit, query, sort))
if preloadQuery != nil {
preloadAssociation := *preloadQuery
queryDB = queryDB.Preload(preloadAssociation)
}
if result := queryDB.Find(&data).Error; result != nil {
return nil, result
}
paginatedResult := &response.PaginationDTO{
Docs: data,
TotalPages: int64(totalPages),
TotalDocs: totalRows,
Page: parsePage,
Limit: parseLimit,
}
return paginatedResult, nil
}