Your Question
My question is about how to customize jointable. The example shown in doc is
type Person struct {
ID int
Name string
Addresses []Address `gorm:"many2many:person_address;"`
}
type Address struct {
ID uint
Name string
}
type PersonAddress struct {
PersonID int `gorm:"primaryKey"`
AddressID int `gorm:"primaryKey"`
CreatedAt time.Time
DeletedAt gorm.DeletedAt
}
func (PersonAddress) BeforeCreate(db *gorm.DB) error {
// ...
}
// 修改 Person 的 Addresses 字段的连接表为 PersonAddress
// PersonAddress 必须定义好所需的外键,否则会报错
err := db.SetupJoinTable(&Person{}, "Addresses", &PersonAddress{})
It points out PersonAddress 必须定义好所需的外键,否则会报错. I am confused how to define foreignKey in this example.
Now this is my own test unit try to use many-to-many relationship
type IP struct {
ID int `json:"ip_id" gorm:"column:ip_id; primaryKey"`
Title string `json:"ip_title" gorm:"column:ip_title"`
Content string `json:"ip_content" gorm:"column:ip_content"`
Status string `json:"ip_status" gorm:"column:ip_status"`
Patents []*Patent `json:"ip_patents" gorm:"foreignKey:patent_ip"`
Managers []*Manager `json:"ip_managers" gorm:"many2many:ip_managedby_table; joinForeignKey:ip_managedby_manager_id;"`
}
type Manager struct {
ID int `json:"manager_id" gorm:"column:manager_id; primaryKey"`
Name string `json:"manager_name" gorm:"column:manager_name"`
IPs []*IP `json:"manager_ips" gorm:"many2many:ip_managedby_table; joinForeignKey:ip_managedby_ip_id;"`
}
type IPManagedBy struct {
IP int `json:"ip_managedby_ip_id" gorm:"column:ip_managedby_ip_id; primaryKey; foreignKey:ip_id; references:IP(ip_id)"`
Manager int `json:"ip_managedby_manager_id" gorm:"column:ip_managedby_manager_id; primaryKey; foreignKey:manager_id; references:Manager(manager_id)"`
}
Now I create these three table
db.Migrator().DropTable(&IPManagedBy{})
db.Migrator().DropTable(&Manager{})
db.Migrator().DropTable(&IP{})
db.AutoMigrate(&IPManagedBy{})
db.AutoMigrate(&IP{})
db.AutoMigrate(&Manager{})
The IP table and Manager table is expected.
However, as for IPManagedBy table, there are two additional schema.
+-------------------------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------------+--------+------+-----+---------+-------+
| ip_managedby_ip_id | bigint | NO | PRI | NULL | |
| ip_managedby_manager_id | bigint | NO | PRI | NULL | |
| ip_id | bigint | YES | MUL | NULL | |
| manager_id | bigint | YES | | NULL | |
+-------------------------+--------+------+-----+---------+-------+
I check the log. the log is like this
2023/04/12 22:22:24 /home/zreal/toyProj/IPM_Internal/sql_test.go:119 SLOW SQL >= 200ms
[805.270ms] [rows:0] DROP TABLE IF EXISTS `ip_managedby_table` CASCADE
2023/04/12 22:22:25 /home/zreal/toyProj/IPM_Internal/sql_test.go:120 SLOW SQL >= 200ms
[981.382ms] [rows:0] DROP TABLE IF EXISTS `manager_table` CASCADE
2023/04/12 22:22:25 /home/zreal/toyProj/IPM_Internal/sql_test.go:121 SLOW SQL >= 200ms
[491.566ms] [rows:0] DROP TABLE IF EXISTS `ip_table` CASCADE
2023/04/12 22:22:26 /home/zreal/toyProj/IPM_Internal/sql_test.go:123 SLOW SQL >= 200ms
[845.501ms] [rows:0] CREATE TABLE `ip_managedby_table` (`ip_managedby_ip_id` bigint,`ip_managedby_manager_id` bigint,PRIMARY KEY (`ip_managedby_ip_id`,`ip_managedby_manager_id`))
2023/04/12 22:22:27 /home/zreal/toyProj/IPM_Internal/sql_test.go:124 SLOW SQL >= 200ms
[838.488ms] [rows:0] CREATE TABLE `ip_table` (`ip_id` bigint AUTO_INCREMENT,`ip_title` longtext,`ip_content` longtext,`ip_status` longtext,PRIMARY KEY (`ip_id`))
2023/04/12 22:22:28 /home/zreal/toyProj/IPM_Internal/sql_test.go:124 SLOW SQL >= 200ms
[771.384ms] [rows:0] CREATE TABLE `manager_table` (`manager_id` bigint AUTO_INCREMENT,`manager_name` longtext,PRIMARY KEY (`manager_id`))
2023/04/12 22:22:28 /home/zreal/toyProj/IPM_Internal/sql_test.go:124 SLOW SQL >= 200ms
[406.072ms] [rows:0] ALTER TABLE `ip_managedby_table` ADD `ip_id` bigint
2023/04/12 22:22:30 /home/zreal/toyProj/IPM_Internal/sql_test.go:124 SLOW SQL >= 200ms
[1617.418ms] [rows:0] ALTER TABLE `ip_managedby_table` ADD CONSTRAINT `fk_ip_managedby_table_manager` FOREIGN KEY (`ip_managedby_ip_id`) REFERENCES `manager_table`(`manager_id`)
2023/04/12 22:22:32 /home/zreal/toyProj/IPM_Internal/sql_test.go:124 SLOW SQL >= 200ms
[2016.046ms] [rows:0] ALTER TABLE `ip_managedby_table` ADD CONSTRAINT `fk_ip_managedby_table_ip` FOREIGN KEY (`ip_id`) REFERENCES `ip_table`(`ip_id`)
2023/04/12 22:22:32 /home/zreal/toyProj/IPM_Internal/sql_test.go:125 SLOW SQL >= 200ms
[539.352ms] [rows:0] ALTER TABLE `ip_managedby_table` ADD `manager_id` bigint
There are some operation to alter table.
I want to know the complete process to add foreignKey constrain when customizing jointable.
The document you expected this should be explained
Expected answer
Comment From: Zrealshadow
I fix above problem, Maybe we should add some more detailed example for many-to-many usage, especially involving all features like overwrite foreignkey and customize jointable
Comment From: a631807682
Thanks for your feedback, are you interested in creating a PR for it? Documentation project is at https://github.com/go-gorm/gorm.io
Comment From: github-actions[bot]
This issue has been automatically marked as stale because it has been open 360 days with no activity. Remove stale label or comment or this will be closed in 180 days