has one establishes a one-to-one relationship with another model, but it is slightly different from a one-to-one relationship. This association indicates that each instance of one model contains or owns an instance of the other model.
For example, your application contains user and credit card models, and each user can only have one credit card.
- Create model
// User 有一张 CreditCard,UserID 是外键
type User struct {
gorm.Model
CreditCard CreditCard
}
type CreditCard struct {
gorm.Model
Number string
UserID uint
}
For has one relationships, foreign key fields must also exist. The owner will save the primary key of the model belonging to it to this field.
The name of this field is usually generated by the has one model's type plus its primary key, for the above example it is UserID.
When a credit card is added for a user, it saves the user's ID into its own UserID field.
If you want to use another field to hold the relationship, you can also change it using the tag foreignKey, for example:
// User 有一张 CreditCard,UserName 是外键
type User struct {
gorm.Model
CreditCard CreditCard `gorm:"foreignKey:UserName"` // 使用 UserName 作为外键
}
type CreditCard struct {
gorm.Model
Number string
UserName string //存储user表的主键id
}
- Create table
package mysqltest
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
var db *gorm.DB
func Initdb() {
dsn := "ellis:ellis@tcp(192.168.214.134:3306)/go_db?charset=utf8mb4&parseTime=True&loc=Local"
var err error
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
})
if err != nil {
panic(err)
}
}
func Create(value interface{
}) {
d := db.Create(value)
fmt.Printf("d.RowsAffected: %v\n", d.RowsAffected)
}
func InitTable() {
db.AutoMigrate(&User{
}, &CreditCard{
})
}
- Polymorphic
GORM provides polymorphic association support for has one and has many. It will save the table name and primary key value of the owner entity into polymorphic type fields.
type Toy struct {
ID int
Name string
OwnerID int
OwnerType string
}
type Cat struct {
ID int
Name string
Toy Toy `gorm:"polymorphic:Owner;"`
}
type Dog struct {
ID int
Name string
Toy Toy `gorm:"polymorphic:Owner;"`
}
db.Create(&Dog{
Name: "dog1", Toy: Toy{
Name: "toy1"}})