HasOne

HasOne

has one アソシエーションは、別のモデルとの一対一の関係をセットアップしますが、セマンティクス(および結果)はやや異なります。このアソシエーションは、モデルの各インスタンスが別のモデルの1つのインスタンスを含んでいる、または所有していることを示します。

たとえば、アプリケーションにユーザーとクレジットカードが含まれており、各ユーザーが1つのクレジットカードしか持てない場合を考えてみましょう。

宣言

// User has one CreditCard, UserID is the foreign key
type User struct {
gorm.Model
CreditCard CreditCard
}

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

取得

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

外部キーの上書き

has one の関係では、外部キーフィールドも存在する必要があります。所有者は、それに属するモデルの主キーをこのフィールドに保存します。

フィールド名は通常、has one モデルの型とその主キーを使用して生成されます。上記の例では、UserIDです。

ユーザーにクレジットカードを付与すると、ユーザーのIDがそのUserIDフィールドに保存されます。

関係の保存に別のフィールドを使用したい場合は、タグforeignKeyを使用して変更できます。例:

type User struct {
gorm.Model
CreditCard CreditCard `gorm:"foreignKey:UserName"`
// use UserName as foreign key
}

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

参照の上書き

デフォルトでは、所有エンティティはhas oneモデルの主キーを外部キーに保存します。下記の例のように、別のフィールドの値を保存するように変更できます。

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

type User struct {
gorm.Model
Name string `gorm:"index"`
CreditCard CreditCard `gorm:"foreignKey:UserName;references:name"`
}

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

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

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

type Cat struct {
ID int
Name string
Toy Toy `gorm:"polymorphic:Owner;"`
}

type Dog struct {
ID int
Name string
Toy Toy `gorm:"polymorphic:Owner;"`
}

type Toy struct {
ID int
Name string
OwnerID int
OwnerType string
}

db.Create(&Dog{Name: "dog1", Toy: Toy{Name: "toy1"}})
// INSERT INTO `dogs` (`name`) VALUES ("dog1")
// INSERT INTO `toys` (`name`,`owner_id`,`owner_type`) VALUES ("toy1","1","dogs")

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

type Dog struct {
ID int
Name string
Toy 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"}})
// INSERT INTO `dogs` (`name`) VALUES ("dog1")
// INSERT INTO `toys` (`name`,`owner_id`,`owner_type`) VALUES ("toy1","1","master")

HasOneを使用したCRUD

has one関係の操作については、アソシエーションモードをご覧ください。

早期読み込み

GORMでは、PreloadまたはJoinsを使用してhas oneアソシエーションの早期読み込みが可能です。詳細はプリロード(早期読み込み)を参照してください。

自己参照HasOne

type User struct {
gorm.Model
Name string
ManagerID *uint
Manager *User
}

外部キー制約

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

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

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

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

プラチナスポンサー

ゴールドスポンサー

プラチナスポンサー

ゴールドスポンサー