アソシエーションの自動作成/更新 GORMはレコードの作成・更新時にUpsert を使用して自動的に関連データとその参照を保存します。
user := User{ Name: "jinzhu" , BillingAddress: Address{Address1: "Billing Address - Address 1" }, ShippingAddress: Address{Address1: "Shipping Address - Address 1" }, Emails: []Email{ {Email: "jinzhu@example.com" }, {Email: "jinzhu-2@example.com" }, }, Languages: []Language{ {Name: "ZH" }, {Name: "EN" }, }, } db.Create(&user) db.Save(&user)
すでに存在するアソシエーションレコードを更新したい場合は、 FullSaveAssociations
を使用してください。
db.Session(&gorm.Session{FullSaveAssociations: true }).Updates(&user)
アソシエーションの自動作成/更新をスキップ 作成/更新時のアソシエーションレコードの自動保存をスキップするには、 Select
または Omit
を使用します。例:
user := User{ Name: "jinzhu" , BillingAddress: Address{Address1: "Billing Address - Address 1" }, ShippingAddress: Address{Address1: "Shipping Address - Address 1" }, Emails: []Email{ {Email: "jinzhu@example.com" }, {Email: "jinzhu-2@example.com" }, }, Languages: []Language{ {Name: "ZH" }, {Name: "EN" }, }, } db.Select("Name" ).Create(&user) db.Omit("BillingAddress" ).Create(&user) db.Omit(clause.Associations).Create(&user)
注意: many2many(多対多)のアソシエーションの場合、中間テーブルのレコードを作成するより前に、アソシエーション先テーブルのレコードをupsertします。アソシエーション先へのupsertを省略したい場合は、以下のように記載します。
db.Omit("Languages.*" ).Create(&user)
次のコードはアソシエーション先のレコードの作成と中間テーブルでの参照の作成の両方をスキップします。
db.Omit("Languages" ).Create(&user)
アソシエーションフィールドの選択/省略 user := User{ Name: "jinzhu" , BillingAddress: Address{Address1: "Billing Address - Address 1" , Address2: "addr2" }, ShippingAddress: Address{Address1: "Shipping Address - Address 1" , Address2: "addr2" }, } db.Select("BillingAddress.Address1" , "BillingAddress.Address2" ).Create(&user) db.Omit("BillingAddress.Address2" , "BillingAddress.CreatedAt" ).Create(&user)
Association Mode Association Mode には、データの関連を処理するためによく使用されるヘルパーメソッドが含まれています。
var user Userdb.Model(&user).Association("Languages" ) db.Model(&user).Association("Languages" ).Error
関連の取得 関連レコードを取得することができます。
db.Model(&user).Association("Languages" ).Find(&languages)
条件を指定して関連を取得することも可能です。
codes := []string {"zh-CN" , "en-US" , "ja-JP" } db.Model(&user).Where("code IN ?" , codes).Association("Languages" ).Find(&languages) db.Model(&user).Where("code IN ?" , codes).Order("code desc" ).Association("Languages" ).Find(&languages)
関連の追加 many to many
や has many
の場合には関連を追加し、 has one
や belongs to
の場合には現在の関連を置き換えます。
db.Model(&user).Association("Languages" ).Append([]Language{languageZH, languageEN}) db.Model(&user).Association("Languages" ).Append(&Language{Name: "DE" }) db.Model(&user).Association("CreditCard" ).Append(&CreditCard{Number: "411111111111" })
関連を置き換える 現在の関連を新しいもので置き換えることができます。
db.Model(&user).Association("Languages" ).Replace([]Language{languageZH, languageEN}) db.Model(&user).Association("Languages" ).Replace(Language{Name: "DE" }, languageEN)
関連を削除する 引数で指定された値との関連がある場合、その値との関連を削除します。削除されるのは参照のみであり、参照先オブジェクトのレコードはDBから削除されません。
db.Model(&user).Association("Languages" ).Delete([]Language{languageZH, languageEN}) db.Model(&user).Association("Languages" ).Delete(languageZH, languageEN)
関連を全て削除する 関連データとの参照を全て削除することができます。削除されるのは参照のみであり、参照先のレコードは削除されません。
db.Model(&user).Association("Languages" ).Clear()
関連の数を取得する 現在の関連の数を取得することができます。
db.Model(&user).Association("Languages" ).Count() codes := []string {"zh-CN" , "en-US" , "ja-JP" } db.Model(&user).Where("code IN ?" , codes).Association("Languages" ).Count()
一括データ処理 Association Mode はデータの一括処理もサポートしています。例:
db.Model(&users).Association("Role" ).Find(&roles) db.Model(&users).Association("Team" ).Delete(&userA) db.Model(&users).Association("Team" ).Count() var users = []User{user1, user2, user3}db.Model(&users).Association("Team" ).Append(&userA, &userB, &[]User{userA, userB, userC}) db.Model(&users).Association("Team" ).Replace(&userA, &userB, &[]User{userA, userB, userC})
関連を指定して削除する レコード削除時に Select
を使用することで、has one / has many / many2many 関係にある関連も同時に削除することができます。例:
db.Select("Account" ).Delete(&user) db.Select("Orders" , "CreditCards" ).Delete(&user) db.Select(clause.Associations).Delete(&user) db.Select("Account" ).Delete(&users)
注意: レコード削除時の主キーが非ゼロ値の場合のみ、関連レコードの削除も可能となります。GORMは指定の関連を削除するための条件として主キーを使用します。
db.Select("Account" ).Where("name = ?" , "jinzhu" ).Delete(&User{}) db.Select("Account" ).Where("name = ?" , "jinzhu" ).Delete(&User{ID: 1 }) db.Select("Account" ).Delete(&User{ID: 1 })
アソシエーションで使用できるタグ
タグ
説明
foreignKey
テーブル結合時に、これを指定したモデルの外部キーとして使用するフィールド名を指定できます
references
テーブル結合時に、参照先テーブルの外部キーとして使用するフィールド名を指定できます
polymorphic
モデル名などのポリモーフィック関連の種別を指定できます
polymorphicValue
ポリモーフィック関連ので使用される値を指定できます。デフォルトはテーブル名です。
many2many
結合テーブル名を指摘できます
joinForeignKey
テーブル結合時に、これを指定したモデルの外部キーとして使用する結合テーブルのカラム名を指定できます
joinReferences
テーブル結合時に、参照先テーブルの外部キーとして使用する結合テーブルのカラム名を指定できます
constraint
参照制約を指定できます。例:OnUpdate
, OnDelete