# Has Many
## Has Many
`has many` 与另一个模型建立了一对多的连接。 不同于 `has one`,拥有者可以有零或多个关联模型。
例如,您的应用包含 user 和 credit card 模型,且每个 user 可以有多张 credit card。
~~~
// User 有多张 CreditCard,UserID 是外键
type User struct {
gorm.Model
CreditCards []CreditCard
}
type CreditCard struct {
gorm.Model
Number string
UserID uint
}
~~~
~~~
type User struct {
gorm.Model
CreditCards []CreditCard `gorm:"foreignKey:UserRefer"`
}
type CreditCard struct {
gorm.Model
Number string
UserRefer uint
}
~~~
~~~
type User struct {
gorm.Model
MemberNumber string
CreditCards []CreditCard `gorm:"foreignKey:UserNumber;references:MemberNumber"`
}
type CreditCard struct {
gorm.Model
Number string
UserNumber string
}
~~~
~~~
type Dog struct {
ID int
Name string
Toys []Toy `gorm:"polymorphic:Owner;"`
}
type Toy struct {
ID int
Name string
OwnerID int
OwnerType string
}
db.Create(&Dog{Name: "dog1", Toy: []Toy{{Name: "toy1"}, {Name: "toy2"}}})
// INSERT INTO `dogs` (`name`) VALUES ("dog1")
// INSERT INTO `toys` (`name`,`owner_id`,`owner_type`) VALUES ("toy1","1","dogs"), ("toy2","1","dogs")
~~~
~~~
type Dog struct {
ID int
Name string
Toys []Toy `gorm:"polymorphic:Owner;polymorphicValue:master"`
}
type Toy struct {
ID int
Name string
OwnerID int
OwnerType string
}
db.Create(&Dog{Name: "dog1", Toy: []Toy{{Name: "toy1"}, {Name: "toy2"}}})
// INSERT INTO `dogs` (`name`) VALUES ("dog1")
// INSERT INTO `toys` (`name`,`owner_id`,`owner_type`) VALUES ("toy1","1","master"), ("toy2","1","master")
~~~
~~~
type User struct {
gorm.Model
Name string
ManagerID *uint
Team []User `gorm:"foreignkey:ManagerID"`
}
~~~
~~~
type User struct {
gorm.Model
CreditCards []CreditCard `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
}
type CreditCard struct {
gorm.Model
Number string
UserID uint
}
~~~
你可以通过标签 `constraint` 并带上 `OnUpdate`、`OnDelete` 实现外键约束,例如:
## 外键约束
## 自引用 Has Many
GORM 可以通过 `Preload` 预加载 has many 关联的记录,查看 [预加载](./preload.md) 获取详情
## 预加载
查看 [关联模式](./associations.md#Association-Mode) 获取 has many 相关的用法
## Has Many 的 CURD
您可以使用标签 `polymorphicValue` 来更改多态类型的值,例如:
GORM 为 `has one` 和 `has many` 提供了多态关联支持,它会将拥有者实体的表名、主键都保存到多态类型的字段中。
## 多态关联
同样的,您也可以使用标签 `references` 来更改它,例如:
为 user 添加 credit card 时,GORM 会将 user 的 `ID` 字段保存到 credit card 的 `UserID` 字段。
GORM 通常使用拥有者的主键作为外键的值。 对于上面的例子,它是 `User` 的 `ID` 字段。
## 重写引用
此外,想要使用另一个字段作为外键,您可以使用 `foreignKey` 标签自定义它:
例如,要定义一个属于 `User` 的模型,则其外键应该是 `UserID`。
要定义 `has many` 关系,同样必须存在外键。 默认的外键名是拥有者的类型名加上其主键字段名
## 重写外键