From 006dc4a2b23ac9e77699feb3ded658d8ab850c5b Mon Sep 17 00:00:00 2001 From: Hein Date: Tue, 11 Nov 2025 11:58:41 +0200 Subject: [PATCH] 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 --- .gitignore | 3 ++- pkg/common/adapters/database/bun.go | 4 ++++ pkg/common/adapters/database/gorm.go | 7 +++++++ pkg/common/interfaces.go | 1 + pkg/restheadspec/handler.go | 2 +- 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 9d03e21..a37e8ec 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,5 @@ go.work.sum # env file .env -bin/ \ No newline at end of file +bin/ +test.db diff --git a/pkg/common/adapters/database/bun.go b/pkg/common/adapters/database/bun.go index a28e13b..5ae0c73 100644 --- a/pkg/common/adapters/database/bun.go +++ b/pkg/common/adapters/database/bun.go @@ -238,6 +238,10 @@ func (b *BunSelectQuery) Scan(ctx context.Context, dest interface{}) error { 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) { // If Model() was set, use bun's native Count() which works properly if b.hasModel { diff --git a/pkg/common/adapters/database/gorm.go b/pkg/common/adapters/database/gorm.go index 7da609a..0c4dc11 100644 --- a/pkg/common/adapters/database/gorm.go +++ b/pkg/common/adapters/database/gorm.go @@ -221,6 +221,13 @@ func (g *GormSelectQuery) Scan(ctx context.Context, dest interface{}) 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) { var count int64 err := g.db.WithContext(ctx).Count(&count).Error diff --git a/pkg/common/interfaces.go b/pkg/common/interfaces.go index 1c116e2..1599ee9 100644 --- a/pkg/common/interfaces.go +++ b/pkg/common/interfaces.go @@ -39,6 +39,7 @@ type SelectQuery interface { // Execution methods Scan(ctx context.Context, dest interface{}) error + ScanModel(ctx context.Context) error Count(ctx context.Context) (int, error) Exists(ctx context.Context) (bool, error) } diff --git a/pkg/restheadspec/handler.go b/pkg/restheadspec/handler.go index 6e7b024..e01f531 100644 --- a/pkg/restheadspec/handler.go +++ b/pkg/restheadspec/handler.go @@ -398,7 +398,7 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st } // 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) h.sendError(w, http.StatusInternalServerError, "query_error", "Error executing query", err) return