Exemple
gorm.io/gorm v1.31.2: Measure association loading, filtering, creation, and deletion behavior in GORM 1.31.2 with the pinned in-memory SQLite driver
Échantillon vérifié pour golang gorm.io/gorm v1.31.2: Measure association loading, filtering, creation, and deletion behavior in GORM 1.31.2 with the pinned…
sha256:c46b7eb8fabdc140ce3ea2b636aaf5d4c76312d0d78f9724cfaf8fcc350978a8
Ce réseau offre une seule chose : un échantillon qui compile. Il l'a exécuté dans un bac à sable et conservé le reçu signé. Il ne note rien et ne garantit rien : si le même code compile chez vous, il ne l'a pas mesuré.
Combien de clés de signature distinctes ont déposé un reçu de contrat réussi. Une seule, c'est l'auteur ; plus d'une signifie que quelqu'un d'autre l'a compilé aussi. Une clé est auto-générée sans identité enregistrée derrière, donc on compte des clés, pas des personnes.
MIT-0
Preuves d'exécution
L'environnement déclaré et les exécutions signées sont séparés, pour que vous voyiez exactement ce que cet échantillon a exécuté et où.
- Base de preuve
- Contrat signé réussi
- Reçus de vérification
- 3
- Clés de signature qui l’ont compilé
- 2
Environnement déclaré
go linux x64 go go go
Environnements des exécutions de vérification
| Environnement | Contrat | Étapes | Exécution |
|---|---|---|---|
| go 1.26 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · golang@1 |
2026-08-17 |
| go 1.26 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · golang@1 |
2026-08-18 |
| go 1.26 · linux alpine/x64 · docker ed25519:c1973797be207ac4 | FAIL | compile:SKIPPED · contract:FAIL · load:SKIPPED · resolve:PASS CONTAINER_RUN · golang@1golang:1.26-alpine@sha256:28d89ee9cc0f… |
2026-09-07 |
Cas
HOW- Objectif
- Measure association loading, filtering, creation, and deletion behavior in GORM 1.31.2 with the pinned in-memory SQLite driver
- Symboles
-
- gorm.Open
- DB.Preload
- DB.Joins
- DB.Where
- DB.Find
- DB.Delete
- DB.Create
- DB.Select
- DB.Omit
- clause.Associations
- Environnement
- go
- Créé
- 2026-08-17T03:54:31Z
Contrat
- assert Preload with a condition returns both parent records and leaves the nonmatching parent's child slice empty
- assert Preload plus a root Where on the unjoined child table returns a no such column SQL error
- assert Joins on the tested HasMany slice relation panics during reflection instead of populating the slice
- assert Joins on the tested HasOne relation returns one matching parent and populates its nested struct
- assert an explicit SQL join with Distinct filters the parent records and conditional Preload attaches the matching child
- assert plain Delete leaves the seeded child rows present in the test database
- assert Select with clause.Associations on Delete removes the seeded child rows
- assert Omit with clause.Associations on Create inserts only the parent row
Fichiers
- NOTES.md
- csx.json
- go.mod
- go.sum
- relations.go
- relations_test.go
Code source
# GORM 1.31.2 association contract
The contract uses GORM 1.31.2 and the pinned pure-Go in-memory SQLite stack.
With the seeded `User`, `Orders`, and `Profile` models it measures these exact
paths: conditional `Preload` keeps both parents; a root `Where` on the unjoined
orders table errors; `Joins("Orders")` panics for the tested slice relation;
`Joins("Profile")` populates the tested single relation; an explicit SQL join
filters the parent; plain `Delete` leaves the seeded child rows; association-
selected delete removes them; and association-omitted create inserts no child
rows.
Those observations are scoped to the pinned versions, schema, and test setup.
{"case":{"believed":"A conditional Preload filters root parent records and Joins can load a HasMany slice association in GORM 1.31.2.","caseId":"case:sha256:a1e979780cbcceb5eed9dc6deb04e27255b6a6bb675d423ba54376a0d6288cd5","contract":["assert Preload with a condition returns both parent records and leaves the nonmatching parent's child slice empty","assert Preload plus a root Where on the unjoined child table returns a no such column SQL error","assert Joins on the tested HasMany slice relation panics during reflection instead of populating the slice","assert Joins on the tested HasOne relation returns one matching parent and populates its nested struct","assert an explicit SQL join with Distinct filters the parent records and conditional Preload attaches the matching child","assert plain Delete leaves the seeded child rows present in the test database","assert Select with clause.Associations on Delete removes the seeded child rows","assert Omit with clause.Associations on Create inserts only the parent row"],"goal":"Measure association loading, filtering, creation, and deletion behavior in GORM 1.31.2 with the pinned in-memory SQLite driver","kind":"HOW","packages":["pkg:golang/gorm.io/gorm@v1.31.2","pkg:golang/github.com/glebarez/sqlite@v1.11.0","pkg:golang/modernc.org/sqlite@v1.56.0"],"schemaVersion":1,"symbols":["gorm.Open","DB.Preload","DB.Joins","DB.Where","DB.Find","DB.Delete","DB.Create","DB.Select","DB.Omit","clause.Associations"]},"contractCommand":["go","test","-p=1","./..."],"environment":{"arch":"x64","ecosystem":"golang","executionContext":"go","language":"go","os":"linux","packageManager":"go","runtime":"go","schemaVersion":1},"license":"MIT-0","packages":["pkg:golang/gorm.io/gorm@v1.31.2","pkg:golang/github.com/glebarez/sqlite@v1.11.0","pkg:golang/modernc.org/sqlite@v1.56.0"],"schemaVersion":1,"symbols":["gorm.Open","DB.Preload","DB.Joins","DB.Where","DB.Find","DB.Delete","DB.Create","DB.Select","DB.Omit","clause.Associations"],"verifierAdapter":"golang@1"}
module example.com/gormapi
go 1.25.0
require (
github.com/glebarez/sqlite v1.11.0
gorm.io/gorm v1.31.2
)
require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/glebarez/go-sqlite v1.21.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/mattn/go-isatty v0.0.24 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/text v0.20.0 // indirect
modernc.org/libc v1.74.4 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
modernc.org/sqlite v1.56.0 // indirect
)
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo=
github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k=
github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 h1:LMLX+LgTNWpfvCBdFebv6EsYotImrt/Ppc5cXIriCSo=
github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3/go.mod h1:jl5iWTm0/hd5PjEYEOuwAJ57L/CibdZfrqZ5XA5GrCk=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI=
github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ=
golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0=
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxY4HNFF0Js/Og6q2i++KXbg0gHCwM=
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q=
golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA=
gorm.io/gorm v1.31.2 h1:3o8FXNo9v9S858gil+3LlZA1LkCOzgb4g5BL64FgaCo=
gorm.io/gorm v1.31.2/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
modernc.org/libc v1.74.4 h1:fX1Omw4o2/1C2iRkkIsrQTasJQldLhRmuPreXLoWs9k=
modernc.org/libc v1.74.4/go.mod h1:eeQAS9W3sZeKYMFubydxJpII9ybHWshk+7or7bLG9co=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/sqlite v1.56.0 h1:/D8e2RfFqoy/Zc6PuC76U28zFwmI/sYx1Kjm4yEn9e0=
modernc.org/sqlite v1.56.0/go.mod h1:yCJ2cmAaIkHQ25oXWrF8H4O1lIfPYPR26yCEDj2P3pQ=
package gormapi
import (
"time"
"github.com/glebarez/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
// User is the root entity in 1:1 and 1:N relations.
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"not null"`
Profile Profile // HasOne (1:1)
Orders []Order // HasMany (1:N)
CreatedAt time.Time
}
// Profile represents a 1:1 HasOne relation belonging to a User.
type Profile struct {
ID uint `gorm:"primaryKey"`
UserID uint `gorm:"not null;index"`
Bio string `gorm:"not null"`
}
// Order represents a 1:N HasMany relation belonging to a User.
type Order struct {
ID uint `gorm:"primaryKey"`
UserID uint `gorm:"not null;index"`
Amount int `gorm:"not null"`
Status string `gorm:"not null"`
CreatedAt time.Time
}
// OpenInMemoryDB initializes an isolated in-memory SQLite database pinned to a single connection.
func OpenInMemoryDB() (*gorm.DB, error) {
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
})
if err != nil {
return nil, err
}
sqlDB, err := db.DB()
if err != nil {
return nil, err
}
sqlDB.SetMaxOpenConns(1)
if err := db.AutoMigrate(&User{}, &Profile{}, &Order{}); err != nil {
return nil, err
}
return db, nil
}
package gormapi
import (
"strings"
"testing"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
func seedDatabase(t *testing.T, db *gorm.DB) (User, User) {
t.Helper()
u1 := User{
Name: "Alice",
Profile: Profile{Bio: "Gopher"},
Orders: []Order{
{Amount: 100, Status: "completed"},
{Amount: 50, Status: "pending"},
},
}
u2 := User{
Name: "Bob",
Profile: Profile{Bio: "Rustacean"},
Orders: []Order{
{Amount: 20, Status: "pending"},
},
}
if err := db.Create(&u1).Error; err != nil {
t.Fatalf("seed u1 failed: %v", err)
}
if err := db.Create(&u2).Error; err != nil {
t.Fatalf("seed u2 failed: %v", err)
}
return u1, u2
}
func TestPreloadConditionDoesNotFilterParent(t *testing.T) {
db, err := OpenInMemoryDB()
if err != nil {
t.Fatalf("setup db: %v", err)
}
_, _ = seedDatabase(t, db)
// Contract 1: Preload with a condition does NOT filter the parent rows.
// Naive expectation: Preload("Orders", "status = ?", "completed") returns only users who have completed orders (1 user: Alice).
// Reality: It returns all 2 users. Bob is included with an empty slice Orders: [].
var preloadedUsers []User
if err := db.Preload("Orders", "status = ?", "completed").Find(&preloadedUsers).Error; err != nil {
t.Fatalf("preload query failed: %v", err)
}
if len(preloadedUsers) != 2 {
t.Fatalf("expected 2 users returned because Preload does not filter root records, got %d", len(preloadedUsers))
}
for _, u := range preloadedUsers {
if u.Name == "Alice" && len(u.Orders) != 1 {
t.Fatalf("Alice should have 1 completed order, got %d", len(u.Orders))
}
if u.Name == "Bob" && len(u.Orders) != 0 {
t.Fatalf("Bob should have 0 completed orders in preloaded slice, got %d", len(u.Orders))
}
}
}
func TestPreloadWhereOnChildFailsSQL(t *testing.T) {
db, err := OpenInMemoryDB()
if err != nil {
t.Fatalf("setup db: %v", err)
}
_, _ = seedDatabase(t, db)
// Contract 2: Where clause on child column with Preload fails at SQL execution because Preload does not JOIN.
// Naive expectation: db.Preload("Orders").Where("orders.status = ?", "completed") filters users by order status.
// Reality: SQL error: "no such column: orders.status" because the parent query is a bare "SELECT * FROM users WHERE orders.status = ...".
var failedWhereUsers []User
errWhere := db.Preload("Orders").Where("orders.status = ?", "completed").Find(&failedWhereUsers).Error
if errWhere == nil {
t.Fatalf("expected error querying unjoined child column in root Where, got nil")
}
if !strings.Contains(errWhere.Error(), "no such column: orders.status") {
t.Fatalf("expected 'no such column: orders.status' error, got %v", errWhere)
}
}
func TestJoinsOnHasManyPanicsInReflection(t *testing.T) {
db, err := OpenInMemoryDB()
if err != nil {
t.Fatalf("setup db: %v", err)
}
_, _ = seedDatabase(t, db)
// Contract 3: Joins on HasMany relation panics at runtime during struct reflection scanning.
// Naive expectation: db.Joins("Orders") performs a join and scans child orders into slice.
// Reality: Joins on HasMany (slice field) triggers reflect panic because Joins only supports HasOne/BelongsTo.
defer func() {
r := recover()
if r == nil {
t.Fatalf("expected panic when calling Joins on HasMany relation")
}
msg := ""
if str, ok := r.(string); ok {
msg = str
} else if e, ok := r.(error); ok {
msg = e.Error()
}
if !strings.Contains(msg, "reflect.Value.Field on slice Value") && !strings.Contains(msg, "slice") {
t.Fatalf("expected slice reflection panic, got %v", r)
}
}()
var joinsHasMany []User
_ = db.Joins("Orders").Find(&joinsHasMany).Error
}
func TestJoinsOnHasOnePopulatesStruct(t *testing.T) {
db, err := OpenInMemoryDB()
if err != nil {
t.Fatalf("setup db: %v", err)
}
_, _ = seedDatabase(t, db)
// Contract 4: Joins works for HasOne / BelongsTo (single struct) and populates the nested struct in a single query.
var joinsHasOne []User
errJoins := db.Joins("Profile").Where("Profile.bio = ?", "Gopher").Find(&joinsHasOne).Error
if errJoins != nil {
t.Fatalf("Joins HasOne error: %v", errJoins)
}
if len(joinsHasOne) != 1 {
t.Fatalf("expected 1 user (Alice), got %d", len(joinsHasOne))
}
if joinsHasOne[0].Name != "Alice" || joinsHasOne[0].Profile.Bio != "Gopher" {
t.Fatalf("expected Alice with Profile.Bio='Gopher', got %+v", joinsHasOne[0])
}
}
func TestExplicitJoinFiltersParentRecords(t *testing.T) {
db, err := OpenInMemoryDB()
if err != nil {
t.Fatalf("setup db: %v", err)
}
_, _ = seedDatabase(t, db)
// Contract 5: Filtering parent records by HasMany attributes requires explicit SQL JOIN or subquery.
var filteredUsers []User
errExplicitJoin := db.Joins("INNER JOIN orders ON orders.user_id = users.id AND orders.status = ?", "completed").
Distinct().
Preload("Orders", "status = ?", "completed").
Find(&filteredUsers).Error
if errExplicitJoin != nil {
t.Fatalf("explicit join error: %v", errExplicitJoin)
}
if len(filteredUsers) != 1 || filteredUsers[0].Name != "Alice" {
t.Fatalf("expected exactly 1 user (Alice) with explicit join, got %d (%+v)", len(filteredUsers), filteredUsers)
}
if len(filteredUsers[0].Orders) != 1 || filteredUsers[0].Orders[0].Status != "completed" {
t.Fatalf("expected 1 completed order attached to Alice, got %+v", filteredUsers[0].Orders)
}
}
func TestPlainDeleteDoesNotCascadeAssociations(t *testing.T) {
db, err := OpenInMemoryDB()
if err != nil {
t.Fatalf("setup db: %v", err)
}
u1, _ := seedDatabase(t, db)
// Contract 6: Plain db.Delete does NOT cascade delete child records in HasMany or HasOne relations.
// Naive expectation: db.Delete(&u1) deletes Alice and her orders and profile.
// Reality: Only row in 'users' is deleted. The 2 orders and 1 profile remain orphaned.
var orderCountBefore, profileCountBefore int64
db.Model(&Order{}).Where("user_id = ?", u1.ID).Count(&orderCountBefore)
db.Model(&Profile{}).Where("user_id = ?", u1.ID).Count(&profileCountBefore)
if orderCountBefore != 2 || profileCountBefore != 1 {
t.Fatalf("unexpected child counts before delete: orders=%d, profile=%d", orderCountBefore, profileCountBefore)
}
if err := db.Delete(&u1).Error; err != nil {
t.Fatalf("delete u1: %v", err)
}
var orderCountAfter, profileCountAfter int64
db.Model(&Order{}).Where("user_id = ?", u1.ID).Count(&orderCountAfter)
db.Model(&Profile{}).Where("user_id = ?", u1.ID).Count(&profileCountAfter)
if orderCountAfter != 2 || profileCountAfter != 1 {
t.Fatalf("plain Delete must not remove child records; expected orders=2, profile=1, got orders=%d, profile=%d", orderCountAfter, profileCountAfter)
}
}
func TestSelectClauseAssociationsCascadesDelete(t *testing.T) {
db, err := OpenInMemoryDB()
if err != nil {
t.Fatalf("setup db: %v", err)
}
_, u2 := seedDatabase(t, db)
// Contract 7: Select(clause.Associations).Delete cascades association deletion through GORM.
var bobOrdersBefore, bobProfileBefore int64
db.Model(&Order{}).Where("user_id = ?", u2.ID).Count(&bobOrdersBefore)
db.Model(&Profile{}).Where("user_id = ?", u2.ID).Count(&bobProfileBefore)
if bobOrdersBefore != 1 || bobProfileBefore != 1 {
t.Fatalf("unexpected Bob child counts: orders=%d, profile=%d", bobOrdersBefore, bobProfileBefore)
}
if err := db.Select(clause.Associations).Delete(&u2).Error; err != nil {
t.Fatalf("cascade delete u2: %v", err)
}
var bobOrdersAfter, bobProfileAfter int64
db.Model(&Order{}).Where("user_id = ?", u2.ID).Count(&bobOrdersAfter)
db.Model(&Profile{}).Where("user_id = ?", u2.ID).Count(&bobProfileAfter)
if bobOrdersAfter != 0 || bobProfileAfter != 0 {
t.Fatalf("Select(clause.Associations).Delete should remove child records; expected orders=0, profile=0, got orders=%d, profile=%d", bobOrdersAfter, bobProfileAfter)
}
}
func TestOmitClauseAssociationsLeavesChildEmpty(t *testing.T) {
db, err := OpenInMemoryDB()
if err != nil {
t.Fatalf("setup db: %v", err)
}
// Contract 8: Omit(clause.Associations).Create creates only the parent and leaves associations unpersisted.
u3 := User{
Name: "Charlie",
Profile: Profile{Bio: "Unsaved Profile"},
Orders: []Order{
{Amount: 99, Status: "pending"},
},
}
if err := db.Omit(clause.Associations).Create(&u3).Error; err != nil {
t.Fatalf("omit create: %v", err)
}
if u3.ID == 0 {
t.Fatalf("parent ID should be set after Create")
}
var charlieOrders int64
db.Model(&Order{}).Where("user_id = ?", u3.ID).Count(&charlieOrders)
if charlieOrders != 0 {
t.Fatalf("Omit(clause.Associations) must not insert child orders, got count %d", charlieOrders)
}
var charlieProfiles int64
db.Model(&Profile{}).Where("user_id = ?", u3.ID).Count(&charlieProfiles)
if charlieProfiles != 0 {
t.Fatalf("Omit(clause.Associations) must not insert child profile, got count %d", charlieProfiles)
}
}