fix: scan relation preloads through configured model
Tests / Unit Tests (push) Failing after 46s
Build , Vet Test, and Lint / Lint Code (push) Successful in 2m48s
Tests / Integration Tests (push) Failing after 19s
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Successful in 2m56s
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Successful in 2m58s
Build , Vet Test, and Lint / Build (push) Failing after 1m32s

This commit is contained in:
2026-08-28 22:55:44 +02:00
parent 105a5e1b87
commit 798bb47e71
3 changed files with 76 additions and 12 deletions
+15 -5
View File
@@ -340,18 +340,28 @@ func (h *Handler) executeRead(ctx context.Context, schema, entity, id string, op
var data interface{}
if id != "" {
singleResult := reflect.New(modelType).Interface()
pkName := reflection.GetPrimaryKeyName(singleResult)
pkName := reflection.GetPrimaryKeyName(model)
query = query.Where(fmt.Sprintf("%s = ?", common.QuoteIdent(pkName)), id)
if err := query.Scan(ctx, singleResult); err != nil {
// Scan through the model configured on the query. Bun rejects Scan with
// a destination when the query preloads a has-many relation.
if err := query.ScanModel(ctx); err != nil {
if err == sql.ErrNoRows {
return nil, nil, fmt.Errorf("record not found")
}
return nil, nil, fmt.Errorf("query error: %w", err)
}
data = singleResult
// The configured model is a slice so the same query construction works
// for both collection and single-record reads. Extract its one result.
scannedResults := reflect.ValueOf(modelPtr).Elem()
if scannedResults.Len() == 0 {
return nil, nil, fmt.Errorf("record not found")
}
data = scannedResults.Index(0).Interface()
} else {
if err := query.Scan(ctx, modelPtr); err != nil {
// Use the model already configured on the query. This is required by
// Bun whenever the query includes a has-many preload.
if err := query.ScanModel(ctx); err != nil {
return nil, nil, fmt.Errorf("query error: %w", err)
}
data = reflect.ValueOf(modelPtr).Elem().Interface()