Has Many

Has Many

has manyアソシエーションは、別のモデルとの一対多の関係を確立します。has oneとは異なり、所有者はゼロ個または複数のモデルインスタンスを持つことができます。

たとえば、アプリケーションにユーザーとクレジットカードが含まれており、各ユーザーは複数のクレジットカードを持つことができる場合を考えてみましょう。

宣言

// User has many CreditCards, UserID is the foreign key
type User struct {
gorm.Model
CreditCards []CreditCard
}

type CreditCard struct {
gorm.Model
Number string
UserID uint
}

取得

// Retrieve user list with eager loading credit cards
func GetAll(db *gorm.DB) ([]User, error) {
var users []User
err := db.Model(&User{}).Preload("CreditCards").Find(&users).Error
return users, err
}

外部キーのオーバーライド

has many関係を定義するには、外部キーが存在する必要があります。デフォルトの外部キー名は、所有者の型名とその主キーフィールドの名前を組み合わせたものです。

たとえば、Userに属するモデルを定義する場合、外部キーはUserIDになります。

別のフィールドを外部キーとして使用するには、foreignKeyタグを使用してカスタマイズできます。例:

type User struct {
gorm.Model
CreditCards []CreditCard `gorm:"foreignKey:UserRefer"`
}

type CreditCard struct {
gorm.Model
Number string
UserRefer uint
}

参照のオーバーライド

GORMは通常、所有者の主キーを外部キーの値として使用します。上記の例では、UserIDです。

ユーザーにクレジットカードを割り当てると、GORMはユーザーのIDをクレジットカードのUserIDフィールドに保存します。

referencesタグを使用して変更できます。例:

type User struct {
gorm.Model
MemberNumber string
CreditCards []CreditCard `gorm:"foreignKey:UserNumber;references:MemberNumber"`
}

type CreditCard struct {
gorm.Model
Number string
UserNumber string
}

ポリモーフィックアソシエーション

GORMはhas onehas manyのポリモーフィックアソシエーションをサポートしています。所有エンティティのテーブル名がポリモーフィック型のフィールドに、主キー値がポリモーフィックフィールドに保存されます。

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", Toys: []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")

polymorphicValueタグを使用してポリモーフィック型の値を変更できます。例:

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", Toys: []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")

Has Manyを使用したCRUD

Has Many関係の操作については、アソシエーションモードを参照してください。

Eager Loading

GORMはPreloadを使用してHas ManyアソシエーションのEager Loadingを許可します。詳細はプリロード(Eager Loading)を参照してください。

自己参照Has Many

type User struct {
gorm.Model
Name string
ManagerID *uint
Team []User `gorm:"foreignkey:ManagerID"`
}

外部キー制約

constraintタグを使用してOnUpdateOnDelete制約を設定できます。GORMでマイグレーションする際に作成されます。例:

type User struct {
gorm.Model
CreditCards []CreditCard `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
}

type CreditCard struct {
gorm.Model
Number string
UserID uint
}

削除時にSelectを使用して選択したHas Manyアソシエーションを削除することもできます。詳細はSelectを使用した削除を参照してください。

プラチナスポンサー

ゴールドスポンサー

プラチナスポンサー

ゴールドスポンサー