Using scan model method for better relation handling. e.g bun When querying has-many or many-to-many relationships, you should use Model instead of the dest parameter in Scan

This commit is contained in:
Hein 2025-11-11 11:58:41 +02:00
parent ecd7b31910
commit 006dc4a2b2
5 changed files with 15 additions and 2 deletions

1
.gitignore vendored
View File

@ -24,3 +24,4 @@ go.work.sum
# env file # env file
.env .env
bin/ bin/
test.db

View File

@ -238,6 +238,10 @@ func (b *BunSelectQuery) Scan(ctx context.Context, dest interface{}) error {
return b.query.Scan(ctx, dest) return b.query.Scan(ctx, dest)
} }
func (b *BunSelectQuery) ScanModel(ctx context.Context) error {
return b.query.Scan(ctx)
}
func (b *BunSelectQuery) Count(ctx context.Context) (int, error) { func (b *BunSelectQuery) Count(ctx context.Context) (int, error) {
// If Model() was set, use bun's native Count() which works properly // If Model() was set, use bun's native Count() which works properly
if b.hasModel { if b.hasModel {

View File

@ -221,6 +221,13 @@ func (g *GormSelectQuery) Scan(ctx context.Context, dest interface{}) error {
return g.db.WithContext(ctx).Find(dest).Error return g.db.WithContext(ctx).Find(dest).Error
} }
func (g *GormSelectQuery) ScanModel(ctx context.Context) error {
if g.db.Statement.Model == nil {
return fmt.Errorf("ScanModel requires Model() to be set before scanning")
}
return g.db.WithContext(ctx).Find(g.db.Statement.Model).Error
}
func (g *GormSelectQuery) Count(ctx context.Context) (int, error) { func (g *GormSelectQuery) Count(ctx context.Context) (int, error) {
var count int64 var count int64
err := g.db.WithContext(ctx).Count(&count).Error err := g.db.WithContext(ctx).Count(&count).Error

View File

@ -39,6 +39,7 @@ type SelectQuery interface {
// Execution methods // Execution methods
Scan(ctx context.Context, dest interface{}) error Scan(ctx context.Context, dest interface{}) error
ScanModel(ctx context.Context) error
Count(ctx context.Context) (int, error) Count(ctx context.Context) (int, error)
Exists(ctx context.Context) (bool, error) Exists(ctx context.Context) (bool, error)
} }

View File

@ -398,7 +398,7 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
} }
// Execute query - modelPtr was already created earlier // Execute query - modelPtr was already created earlier
if err := query.Scan(ctx, modelPtr); err != nil { if err := query.ScanModel(ctx); err != nil {
logger.Error("Error executing query: %v", err) logger.Error("Error executing query: %v", err)
h.sendError(w, http.StatusInternalServerError, "query_error", "Error executing query", err) h.sendError(w, http.StatusInternalServerError, "query_error", "Error executing query", err)
return return