Files
summercms/modules/lagoon/relations.go
Jakub Zych 36092f542c fix(lagoon): warn on after-commit work registered after lagoon:after_commit; correct the OnDatabase example and pivot read guidance (quick-261028-r16)
- flushStatementAfterCommit marks the statement; AfterCommit logs a warning
  when work is buffered on a flushed statement that no longer holds GORM's
  transaction. Log-only: the work still never runs, the write succeeds
- subtests pin the late callback warning, a callback between commit and
  flush, and a reused chained statement staying silent
- README OnDatabase example registers After(gorm:create).Before(commit),
  matching docs/database/transactions.md
- RegisterJoinTable: pivot-ordered reads join the pivot table explicitly;
  a Preload cannot be ordered by a pivot column
2026-10-28 19:45:57 +01:00

34 lines
1.2 KiB
Go

package lagoon
import (
"fmt"
"gorm.io/gorm"
)
// RegisterJoinTable wraps db.SetupJoinTable so a nil db returns an error
// instead of panicking.
//
// Pivot-write contract: pivot tables with business columns (sort_order,
// role, granted_at, granted_by) are never written through
// db.Model(&owner).Association(field).Append/Replace(...). GORM's
// Association Mode has no documented path to set those columns. Writes go
// through an explicit delete-then-bulk-insert (or ON CONFLICT DO UPDATE)
// against the join table directly, in the same transaction as the parent
// save.
//
// Reads in pivot order join the pivot table explicitly: Joins on the join
// table plus Order on its columns. A Preload of the field still loads the
// targets through the pivot model once RegisterJoinTable has run, but GORM
// issues that query without the join table, so ordering it by a pivot
// column fails with a missing FROM-clause entry.
func RegisterJoinTable(db *gorm.DB, owner any, field string, joinModel any) error {
if db == nil {
return fmt.Errorf("lagoon: register join table: db is nil")
}
if err := db.SetupJoinTable(owner, field, joinModel); err != nil {
return fmt.Errorf("lagoon: register join table: %w", err)
}
return nil
}