# 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` 關系,同樣必須存在外鍵。 默認的外鍵名是擁有者的類型名加上其主鍵字段名
## 重寫外鍵