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 }