Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gormschema: supports Customize JoinTable for Standalone mode #51

Merged
merged 5 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,10 @@ The provider supports the following databases:

### Frequently Asked Questions

* **Foreign key constraints not generated correctly** -
If a [Customize JoinTable](https://gorm.io/docs/many_to_many.html#Customize-JoinTable) is defined in the schema,
you need to use the provider as a [Go Program](#as-go-file) and set it up using the `WithJoinTable` option.

for example if those are your models:
* **Foreign key constraints not generated correctly** - When setting up your [Go Program](#as-go-file) and using [Customize JoinTable](https://gorm.io/docs/many_to_many.html#Customize-JoinTable),
you may encounter issues with foreign key constraints. To avoid these issues, ensure that all models, including the join tables, are passed to the `Load` function.

For example if those are your models:
```go
type Person struct {
ID int
Expand All @@ -269,11 +268,7 @@ The provider supports the following databases:

you should use the following code:
```go
stmts, err := gormschema.New("mysql",
gormschema.WithJoinTable(
&Models.Person{}, "Addresses", &Models.PersonAddress{},
),
).Load(&Models.Address{}, &Models.Person{})
stmts, err := gormschema.New("mysql").Load(&Models.Address{}, &Models.Person{}, &Models.PersonAddress{})
```

### License
Expand Down
89 changes: 84 additions & 5 deletions gormschema/gorm.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,24 @@ func (l *Loader) Load(models ...any) (string, error) {
return "", err
}
}
if err = db.AutoMigrate(tables...); err != nil {
return "", err
}
db, err = gorm.Open(dialector{Dialector: di}, l.config)
cdb, err := gorm.Open(dialector{Dialector: di}, l.config)
if err != nil {
return "", err
}
cm, ok := db.Migrator().(*migrator)
cm, ok := cdb.Migrator().(*migrator)
if !ok {
return "", fmt.Errorf("unexpected migrator type: %T", db.Migrator())
}
if err = cm.setupJoinTables(tables...); err != nil {
return "", err
}
orderedTables, err := cm.orderModels(tables...)
if err != nil {
return "", err
}
if err = db.AutoMigrate(orderedTables...); err != nil {
return "", err
}
if err = cm.CreateViews(views); err != nil {
return "", err
}
Expand Down Expand Up @@ -193,6 +200,39 @@ func (m *migrator) CreateConstraints(models []any) error {
return nil
}

// setupJoinTables helps to determine custom join tables present in the model list and sets them up.
func (m *migrator) setupJoinTables(models ...any) error {
var dbNameModelMap = make(map[string]any)
for _, model := range models {
err := m.RunWithValue(model, func(stmt *gorm.Statement) error {
dbNameModelMap[stmt.Schema.Table] = model
return nil
})
if err != nil {
return err
}
}
for _, model := range m.ReorderModels(models, false) {
err := m.RunWithValue(model, func(stmt *gorm.Statement) error {
for _, rel := range stmt.Schema.Relationships.Relations {
if rel.Field.IgnoreMigration || rel.JoinTable == nil {
continue
}
if joinTable, ok := dbNameModelMap[rel.JoinTable.Name]; ok {
if err := m.DB.SetupJoinTable(model, rel.Field.Name, joinTable); err != nil {
return err
}
}
}
return nil
})
if err != nil {
return err
}
}
return nil
}

// CreateViews creates the given "view-based" models
func (m *migrator) CreateViews(views []ViewDefiner) error {
for _, view := range views {
Expand All @@ -217,6 +257,7 @@ func (m *migrator) CreateViews(views []ViewDefiner) error {
}

// WithJoinTable sets up a join table for the given model and field.
// Deprecated: put the join tables alongside the models in the Load call.
func WithJoinTable(model any, field string, jointable any) Option {
return func(l *Loader) {
l.beforeAutoMigrate = append(l.beforeAutoMigrate, func(db *gorm.DB) error {
Expand Down Expand Up @@ -269,3 +310,41 @@ func BuildStmt(fn func(db *gorm.DB) *gorm.DB) ViewOption {
b.createStmt = fmt.Sprintf("CREATE VIEW %s AS %s", b.viewName, vd)
}
}

// orderModels places join tables at the end of the list of models (if any),
// which helps GORM resolve m2m relationships correctly.
func (m *migrator) orderModels(models ...any) ([]any, error) {
var (
joinTableDBNames = make(map[string]bool)
otherTables []any
joinTables []any
)
for _, model := range models {
err := m.RunWithValue(model, func(stmt *gorm.Statement) error {
for _, rel := range stmt.Schema.Relationships.Relations {
if rel.JoinTable != nil {
joinTableDBNames[rel.JoinTable.Table] = true
return nil
}
}
return nil
})
if err != nil {
return nil, err
}
}
for _, model := range models {
err := m.RunWithValue(model, func(stmt *gorm.Statement) error {
if joinTableDBNames[stmt.Schema.Table] {
joinTables = append(joinTables, model)
} else {
otherTables = append(otherTables, model)
}
return nil
})
if err != nil {
return nil, err
}
}
return append(otherTables, joinTables...), nil
}
12 changes: 11 additions & 1 deletion gormschema/gorm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
func TestSQLiteConfig(t *testing.T) {
resetSession()
l := gormschema.New("sqlite")
sql, err := l.Load(models.WorkingAgedUsers{}, models.Pet{}, models.User{}, ckmodels.Event{}, ckmodels.Location{}, models.TopPetOwner{})
sql, err := l.Load(models.WorkingAgedUsers{}, models.Pet{}, ckmodels.Event{}, ckmodels.Location{}, models.TopPetOwner{})
require.NoError(t, err)
requireEqualContent(t, sql, "testdata/sqlite_default")
resetSession()
Expand Down Expand Up @@ -65,6 +65,16 @@ func TestMySQLConfig(t *testing.T) {
sql, err = l.Load(customjointable.Address{}, customjointable.Person{}, customjointable.TopCrowdedAddresses{})
require.NoError(t, err)
requireEqualContent(t, sql, "testdata/mysql_custom_join_table")
resetSession()
l = gormschema.New("mysql")
sql, err = l.Load(customjointable.PersonAddress{}, customjointable.Address{}, customjointable.Person{}, customjointable.TopCrowdedAddresses{})
require.NoError(t, err)
requireEqualContent(t, sql, "testdata/mysql_custom_join_table")
resetSession()
l = gormschema.New("mysql")
sql, err = l.Load(customjointable.Address{}, customjointable.PersonAddress{}, customjointable.Person{}, customjointable.TopCrowdedAddresses{})
require.NoError(t, err)
requireEqualContent(t, sql, "testdata/mysql_custom_join_table") // position of tables should not matter
}

func TestSQLServerConfig(t *testing.T) {
Expand Down
4 changes: 4 additions & 0 deletions gormschema/testdata/mysql_default
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
CREATE TABLE `events` (`eventId` varchar(191),`locationId` varchar(191),PRIMARY KEY (`eventId`),UNIQUE INDEX `idx_events_location_id` (`locationId`));
CREATE TABLE `locations` (`locationId` varchar(191),`eventId` varchar(191),PRIMARY KEY (`locationId`),UNIQUE INDEX `idx_locations_event_id` (`eventId`));
CREATE TABLE `users` (`id` bigint unsigned AUTO_INCREMENT,`created_at` datetime(3) NULL,`updated_at` datetime(3) NULL,`deleted_at` datetime(3) NULL,`name` longtext,`age` bigint,PRIMARY KEY (`id`),INDEX `idx_users_deleted_at` (`deleted_at`));
CREATE TABLE `hobbies` (`id` bigint unsigned AUTO_INCREMENT,`name` longtext,PRIMARY KEY (`id`));
CREATE TABLE `user_hobbies` (`hobby_id` bigint unsigned,`user_id` bigint unsigned,PRIMARY KEY (`hobby_id`,`user_id`));
CREATE TABLE `pets` (`id` bigint unsigned AUTO_INCREMENT,`created_at` datetime(3) NULL,`updated_at` datetime(3) NULL,`deleted_at` datetime(3) NULL,`name` longtext,`user_id` bigint unsigned,PRIMARY KEY (`id`),INDEX `idx_pets_deleted_at` (`deleted_at`));
CREATE VIEW working_aged_users AS SELECT name, age FROM `users` WHERE age BETWEEN 18 AND 65;
CREATE VIEW top_pet_owners AS SELECT user_id, COUNT(id) AS pet_count FROM pets GROUP BY user_id ORDER BY pet_count DESC LIMIT 10;
ALTER TABLE `events` ADD CONSTRAINT `fk_locations_event` FOREIGN KEY (`locationId`) REFERENCES `locations`(`locationId`);
ALTER TABLE `locations` ADD CONSTRAINT `fk_events_location` FOREIGN KEY (`eventId`) REFERENCES `events`(`eventId`);
ALTER TABLE `user_hobbies` ADD CONSTRAINT `fk_user_hobbies_hobby` FOREIGN KEY (`hobby_id`) REFERENCES `hobbies`(`id`);
ALTER TABLE `user_hobbies` ADD CONSTRAINT `fk_user_hobbies_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`);
ALTER TABLE `pets` ADD CONSTRAINT `fk_users_pets` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`);
9 changes: 9 additions & 0 deletions gormschema/testdata/mysql_deterministic_output
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CREATE TABLE `hobbies` (`id` bigint unsigned AUTO_INCREMENT,`name` longtext,PRIMARY KEY (`id`));
CREATE TABLE `users` (`id` bigint unsigned AUTO_INCREMENT,`created_at` datetime(3) NULL,`updated_at` datetime(3) NULL,`deleted_at` datetime(3) NULL,`name` longtext,`age` bigint,PRIMARY KEY (`id`),INDEX `idx_users_deleted_at` (`deleted_at`));
CREATE TABLE `user_hobbies` (`user_id` bigint unsigned,`hobby_id` bigint unsigned,PRIMARY KEY (`user_id`,`hobby_id`));
CREATE TABLE `pets` (`id` bigint unsigned AUTO_INCREMENT,`created_at` datetime(3) NULL,`updated_at` datetime(3) NULL,`deleted_at` datetime(3) NULL,`name` longtext,`user_id` bigint unsigned,PRIMARY KEY (`id`),INDEX `idx_pets_deleted_at` (`deleted_at`));
CREATE VIEW top_pet_owners AS SELECT user_id, COUNT(id) AS pet_count FROM pets GROUP BY user_id ORDER BY pet_count DESC LIMIT 10;
CREATE VIEW working_aged_users AS SELECT name, age FROM `users` WHERE age BETWEEN 18 AND 65;
ALTER TABLE `user_hobbies` ADD CONSTRAINT `fk_user_hobbies_hobby` FOREIGN KEY (`hobby_id`) REFERENCES `hobbies`(`id`);
ALTER TABLE `user_hobbies` ADD CONSTRAINT `fk_user_hobbies_user` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`);
ALTER TABLE `pets` ADD CONSTRAINT `fk_users_pets` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`);
4 changes: 4 additions & 0 deletions gormschema/testdata/postgresql_default
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ CREATE TABLE "locations" ("locationId" varchar(191),"eventId" varchar(191),PRIMA
CREATE UNIQUE INDEX IF NOT EXISTS "idx_locations_event_id" ON "locations" ("eventId");
CREATE TABLE "users" ("id" bigserial,"created_at" timestamptz,"updated_at" timestamptz,"deleted_at" timestamptz,"name" text,"age" bigint,PRIMARY KEY ("id"));
CREATE INDEX IF NOT EXISTS "idx_users_deleted_at" ON "users" ("deleted_at");
CREATE TABLE "hobbies" ("id" bigserial,"name" text,PRIMARY KEY ("id"));
CREATE TABLE "user_hobbies" ("hobby_id" bigint,"user_id" bigint,PRIMARY KEY ("hobby_id","user_id"));
CREATE TABLE "pets" ("id" bigserial,"created_at" timestamptz,"updated_at" timestamptz,"deleted_at" timestamptz,"name" text,"user_id" bigint,PRIMARY KEY ("id"));
CREATE INDEX IF NOT EXISTS "idx_pets_deleted_at" ON "pets" ("deleted_at");
CREATE VIEW working_aged_users AS SELECT name, age FROM "users" WHERE age BETWEEN 18 AND 65;
CREATE VIEW top_pet_owners AS SELECT user_id, COUNT(id) AS pet_count FROM pets GROUP BY user_id ORDER BY pet_count DESC LIMIT 10;
ALTER TABLE "events" ADD CONSTRAINT "fk_locations_event" FOREIGN KEY ("locationId") REFERENCES "locations"("locationId");
ALTER TABLE "locations" ADD CONSTRAINT "fk_events_location" FOREIGN KEY ("eventId") REFERENCES "events"("eventId");
ALTER TABLE "user_hobbies" ADD CONSTRAINT "fk_user_hobbies_hobby" FOREIGN KEY ("hobby_id") REFERENCES "hobbies"("id");
ALTER TABLE "user_hobbies" ADD CONSTRAINT "fk_user_hobbies_user" FOREIGN KEY ("user_id") REFERENCES "users"("id");
ALTER TABLE "pets" ADD CONSTRAINT "fk_users_pets" FOREIGN KEY ("user_id") REFERENCES "users"("id");
2 changes: 2 additions & 0 deletions gormschema/testdata/sqlite_no_fk
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ CREATE TABLE `users` (`id` integer,`created_at` datetime,`updated_at` datetime,`
CREATE INDEX `idx_users_deleted_at` ON `users`(`deleted_at`);
CREATE TABLE `pets` (`id` integer,`created_at` datetime,`updated_at` datetime,`deleted_at` datetime,`name` text,`user_id` integer,PRIMARY KEY (`id`));
CREATE INDEX `idx_pets_deleted_at` ON `pets`(`deleted_at`);
CREATE TABLE `hobbies` (`id` integer,`name` text,PRIMARY KEY (`id`));
CREATE TABLE `user_hobbies` (`hobby_id` integer,`user_id` integer,PRIMARY KEY (`hobby_id`,`user_id`));
4 changes: 4 additions & 0 deletions gormschema/testdata/sqlserver_default
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ CREATE TABLE "locations" ("locationId" nvarchar(191),"eventId" nvarchar(191),PRI
CREATE UNIQUE INDEX "idx_locations_event_id" ON "locations"("eventId");
CREATE TABLE "users" ("id" bigint IDENTITY(1,1),"created_at" datetimeoffset,"updated_at" datetimeoffset,"deleted_at" datetimeoffset,"name" nvarchar(MAX),"age" bigint,PRIMARY KEY ("id"));
CREATE INDEX "idx_users_deleted_at" ON "users"("deleted_at");
CREATE TABLE "hobbies" ("id" bigint IDENTITY(1,1),"name" nvarchar(MAX),PRIMARY KEY ("id"));
CREATE TABLE "user_hobbies" ("hobby_id" bigint,"user_id" bigint,PRIMARY KEY ("hobby_id","user_id"));
CREATE TABLE "pets" ("id" bigint IDENTITY(1,1),"created_at" datetimeoffset,"updated_at" datetimeoffset,"deleted_at" datetimeoffset,"name" nvarchar(MAX),"user_id" bigint,PRIMARY KEY ("id"));
CREATE INDEX "idx_pets_deleted_at" ON "pets"("deleted_at");
CREATE VIEW working_aged_users AS SELECT name, age FROM "users" WHERE age BETWEEN 18 AND 65;
CREATE VIEW top_pet_owners AS SELECT user_id, COUNT(id) AS pet_count FROM pets GROUP BY user_id ORDER BY pet_count DESC OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;
ALTER TABLE "events" ADD CONSTRAINT "fk_locations_event" FOREIGN KEY ("locationId") REFERENCES "locations"("locationId");
ALTER TABLE "locations" ADD CONSTRAINT "fk_events_location" FOREIGN KEY ("eventId") REFERENCES "events"("eventId");
ALTER TABLE "user_hobbies" ADD CONSTRAINT "fk_user_hobbies_hobby" FOREIGN KEY ("hobby_id") REFERENCES "hobbies"("id");
ALTER TABLE "user_hobbies" ADD CONSTRAINT "fk_user_hobbies_user" FOREIGN KEY ("user_id") REFERENCES "users"("id");
ALTER TABLE "pets" ADD CONSTRAINT "fk_users_pets" FOREIGN KEY ("user_id") REFERENCES "users"("id");
2 changes: 1 addition & 1 deletion internal/testdata/customjointable/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type Person struct {
}

type Address struct {
ID int
ID int `gorm:"primaryKey"`
Name string
}

Expand Down
15 changes: 15 additions & 0 deletions internal/testdata/migrations/mysql/20240601122756.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- Create "hobbies" table
CREATE TABLE `hobbies` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`name` longtext NULL,
PRIMARY KEY (`id`)
) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
-- Create "user_hobbies" table
CREATE TABLE `user_hobbies` (
`user_id` bigint unsigned NOT NULL,
`hobby_id` bigint unsigned NOT NULL,
PRIMARY KEY (`user_id`, `hobby_id`),
INDEX `fk_user_hobbies_hobby` (`hobby_id`),
CONSTRAINT `fk_user_hobbies_hobby` FOREIGN KEY (`hobby_id`) REFERENCES `hobbies` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT `fk_user_hobbies_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
3 changes: 2 additions & 1 deletion internal/testdata/migrations/mysql/atlas.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
h1:lKRYkpC/b7av3+2N9ZwAhoInac+KYoj12ZIPaAINpeI=
h1:4neLwABljo1WE/2TflQvcvZCa4xR025viAzNEa4Cp6s=
20230627123246.sql h1:+bgzC3WJyyIR6Rv/FUvaNXJ1gkbKJlYcEMgp69yORIY=
20240512024238.sql h1:2kQL4tE/tAhvXuozmRAJ3oXTo1KRz11QosVDw+0va14=
20240518091603.sql h1:xNClqqRaOjXwg0julpsiPYsmqUcEL/hJel1iqYzi3DM=
20240601122756.sql h1:5+N9UzKTw6qQvJLf8nGw4BdFuHG0fa2JHdHn++G8MuE=
14 changes: 14 additions & 0 deletions internal/testdata/migrations/postgres/20240601122813.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- Create "hobbies" table
CREATE TABLE "public"."hobbies" (
"id" bigserial NOT NULL,
"name" text NULL,
PRIMARY KEY ("id")
);
-- Create "user_hobbies" table
CREATE TABLE "public"."user_hobbies" (
"user_id" bigint NOT NULL,
"hobby_id" bigint NOT NULL,
PRIMARY KEY ("user_id", "hobby_id"),
CONSTRAINT "fk_user_hobbies_hobby" FOREIGN KEY ("hobby_id") REFERENCES "public"."hobbies" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "fk_user_hobbies_user" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
3 changes: 2 additions & 1 deletion internal/testdata/migrations/postgres/atlas.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
h1:LR1ImLA5ZOcbBr9yHMReTtaRiM6dVScC6Xefy3kpxWI=
h1:a/bAYykD/mWdu/8WM16vbYqnwg5NsdX2iM3urGrBFUc=
20230627123049.sql h1:1jYJM2+VCr9152vg6gayCrcEvuT/FE7ufOyZ86VLaOE=
20240512024223.sql h1:RY4w148OJBBr5sXpfBq6B48p/1cFrTEpH4TlwD7mUps=
20240518091611.sql h1:3Kv6mYS8ML72H6HE5qr/a2gdVUrfWuHVufP/1wl70vE=
20240601122813.sql h1:ALbhVYVMyOvZSy5jmBVrsk4xjdkx6ro8OxKJcmW0n1U=
14 changes: 14 additions & 0 deletions internal/testdata/migrations/sqlite/20240601122746.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- Create "hobbies" table
CREATE TABLE `hobbies` (
`id` integer NULL,
`name` text NULL,
PRIMARY KEY (`id`)
);
-- Create "user_hobbies" table
CREATE TABLE `user_hobbies` (
`user_id` integer NULL,
`hobby_id` integer NULL,
PRIMARY KEY (`user_id`, `hobby_id`),
CONSTRAINT `fk_user_hobbies_hobby` FOREIGN KEY (`hobby_id`) REFERENCES `hobbies` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT `fk_user_hobbies_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
);
3 changes: 2 additions & 1 deletion internal/testdata/migrations/sqlite/atlas.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
h1:4HTi5BBlSSs2F/Rg17KQCcuEsVY/dDwyF2yzjThRcd0=
h1:n3NYZrFWODZNTYXEomQ/EtMuxc7EsQDZ7jaIgd9olYY=
20230627123228.sql h1:YfwJdN73sWz1G5/0tU2BtGLyzJCfRQr8blTSquUZ+qo=
20240511123637.sql h1:Kbk3wUzTfBbq8mDdTT08hP93ecNU0y5oTL+O8idEcdQ=
20240518091437.sql h1:svMANRZuZDvgzqO3iyNLUjrUrK8BTMEB2f0NV3d5sJo=
20240601122746.sql h1:Jpzp4UdG5EjO8uNtRWU8sZ9fKuP4mRod5ofyFVQwH1A=
15 changes: 15 additions & 0 deletions internal/testdata/migrations/sqlserver/20240601122612.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- Create "hobbies" table
CREATE TABLE [hobbies] (
[id] bigint IDENTITY (1, 1) NOT NULL,
[name] nvarchar(MAX) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
CONSTRAINT [PK_hobbies] PRIMARY KEY CLUSTERED ([id] ASC)
);
-- Create "user_hobbies" table
CREATE TABLE [user_hobbies] (
[user_id] bigint NOT NULL,
[hobby_id] bigint NOT NULL,
CONSTRAINT [PK_user_hobbies] PRIMARY KEY CLUSTERED ([user_id] ASC, [hobby_id] ASC),

CONSTRAINT [fk_user_hobbies_hobby] FOREIGN KEY ([hobby_id]) REFERENCES [hobbies] ([id]) ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT [fk_user_hobbies_user] FOREIGN KEY ([user_id]) REFERENCES [users] ([id]) ON UPDATE NO ACTION ON DELETE NO ACTION
);
3 changes: 2 additions & 1 deletion internal/testdata/migrations/sqlserver/atlas.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
h1:24mg+pUG3Z4l321YP5s1fRPPaAg6sJC8VR62qPXClTw=
h1:chvbQ1yysFYmq1K82/VfQeLxzMYrhjQ+8xv+2uoXdZw=
20240124151658.sql h1:KaWALlql7BBV3oPVRT4rn+dvZaolhDmgbTgUPxIhauU=
20240512024328.sql h1:IBON1V3jlts+AqxRhejN82SE7/BIXSUWM0SQ0pvw4wc=
20240518091510.sql h1:CCFQHjVI+5dLXCgoPSERCHhyGBZl7QistZlrs1I5170=
20240601122612.sql h1:sCf/0g9oPsaj0Z3l7WO2BjthUwsK9OfPWv80J/L1WCA=
13 changes: 10 additions & 3 deletions internal/testdata/models/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@ import (

type User struct {
gorm.Model
Name string
Age int
Pets []Pet
Name string
Age int
Pets []Pet
Hobbies []Hobby `gorm:"many2many:user_hobbies;"`
}

type Hobby struct {
ID uint
Name string
Users []User `gorm:"many2many:user_hobbies;"`
}

type WorkingAgedUsers struct {
Expand Down
Loading
Loading