自動作成/更新
GORM は、作成またはレコード更新時に、アソシエーションとその参照を自動的に保存します。これには、既存のアソシエーションの外部キーの参照を更新する upsert 手法が使用されます。
作成時のアソシエーションの自動保存
GORM は、新しいレコードを作成すると、関連するデータを自動的に保存します。これには、関連するテーブルへのデータ挿入や外部キーの参照の管理が含まれます。
user := User{ |
FullSaveAssociations
を使用したアソシエーションの更新
関連するデータの完全な更新が必要になるシナリオ(外部キーの参照だけではなく)では、FullSaveAssociations
モードを使用する必要があります。
// Update a user and fully update all its associations |
FullSaveAssociations
を使用することで、モデルのすべての状態が、その関連付けを含めてデータベースに反映され、アプリケーション全体でデータの整合性と一貫性が維持されます。
自動作成/更新のスキップ
GORM は、作成または更新操作中に関連付けの自動保存をスキップするための柔軟性があります。これは、Select
または Omit
メソッドを使用して、操作に含めるまたは除外するフィールドまたは関連付けを正確に指定することで実現できます。
Select
を使用して特定のフィールドを含める
Select
メソッドを使用すると、モデルのどのフィールドを保存するかを指定できます。これは、選択したフィールドのみが SQL 操作に含まれることを意味します。
user := User{ |
Omit
を使用してフィールドまたはアソシエーションを除外する
逆に、Omit
を使用すると、モデルの保存時に特定のフィールドまたは関連付けを除外できます。
// Skip creating the 'BillingAddress' when creating the user |
注意
多対多のアソシエーションでは、GORM は結合テーブルの参照を作成する前にアソシエーションを upsert します。この upsert をスキップするには、関連付けの名前に続けて.*
を指定してOmit
を使用します。
// Skip upserting 'Languages' associations
db.Omit("Languages.*").Create(&user)関連付けとその参照の両方の作成をスキップするには
// Skip creating 'Languages' associations and their references
db.Omit("Languages").Create(&user)
Select
と Omit
を使用することで、関連付けの作成または更新の処理方法を GORM に微調整できます。これにより、アソシエーションの自動保存の動作を制御できます。
アソシエーションのフィールドの Select/Omit
GORM では、レコードを作成または更新するときに、Select
メソッドと Omit
メソッドを使用して、関連モデルの特定のフィールドを具体的に含めたり除外したりできます。
Select
では、プライマリモデルを保存するときに関連モデルのどのフィールドを含めるか指定できます。これは、関連付けの一部を独自に保存する場合に特に役立ちます。
逆に、Omit
は関連付けられているモデルの特定のフィールドが保存されるのを除外することができます。これらは関連付けの特定部分が永続化されないようにしたいときに便利です。
user := User{ |
削除の関連付け
GORMは削除のメインレコードを実行するときにSelect
メソッドを使用して削除関連関係(1つ、多く、多数2以上)を可能にします。この機能は特にデータベースの整合性を維持し、関連データが削除されたときに適切に管理される事を保証するのに便利です。
Select
を使用することによって、メインレコードとともに削除される関連付けを指定することができます。
// Delete a user's account when deleting the user |
注意
関連付けが削除されるのは削除側のレコードの主キーが0ではない時にのみであることを認識することが重要です。GORMはこれらの主キーを条件として選択した関連付けを削除します。
// This will not work as intended
db.Select("Account").Where("name = ?", "jinzhu").Delete(&User{})
// SQL: Deletes all users with name 'jinzhu', but their accounts won't be deleted
// Correct way to delete a user and their account
db.Select("Account").Where("name = ?", "jinzhu").Delete(&User{ID: 1})
// SQL: Deletes the user with name 'jinzhu' and ID '1', and the user's account
// Deleting a user with a specific ID and their account
db.Select("Account").Delete(&User{ID: 1})
// SQL: Deletes the user with ID '1', and the user's account
関連付けモード
GORMの関連付けモードはモデル間の関係を扱う多様なヘルパーメソッドを提供しており、関連付けデータの効率的な管理方法を提供します。
関連付けモードを開始するには、ソースモデルと関連付けフィールド名を指定します。ソースモデルは主キーを含んでおり、関連付けのフィールド名は既存の関連付けに一致しなければなりません。
var user User |
関連付けの検出
追加条件の有無に関わらず、関連付けられたレコードを検索します。
// Simple find |
関連付けの追加
many to many
、has many
用に新しい関連付けを追加するか、has one
、belongs to
の現在の関連付けを置換します。
// Append new languages |
関連付けの置換
現在の関連付けを新しいものと置き換えます。
// Replace existing languages |
関連付けの削除
ソースと引数の間の関係を削除し、参照のみを削除します。
// Delete specific languages |
関連付けのクリア
ソースと関連付けの間のすべての参照を削除します。
// Clear all languages |
関連付けの計算
現在の関連付けの数を条件の有無に関わらず取得します。
// Count all languages |
バッチデータ処理
関連付けモードを使用すると、バッチで複数のレコードの関連付けを処理できます。これには、関連データの検出、追加、置換、削除、およびカウントの操作が含まれます。
- 関連付けの検出: レコードの関連付けデータを検索します。
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} |
関連付けレコードの削除
GORMでは、関連付けモードのReplace
、Delete
、Clear
メソッドは主に関連付けられたレコード自体ではなく外部キーを参照に影響を与えます。この動作を理解して管理することはデータの整合性にとって不可欠です。
- 参照の更新: これらのメソッドは関連付けの外部キーをnullに更新し、実質的にソースと関連付けモデル間のリンクを削除します。
- 物理レコードの削除なし: 実際の関連レコードはデータベース内でそのまま保持されます。
Unscoped
を使用した削除動作の変更
関連レコードの実際の削除が必要なシナリオでは、Unscoped
メソッドがこの動作を変更します。
- ソフト削除: 関連レコードに削除マークを付けます (
deleted_at
フィールドを設定) が、データベースから削除するわけではありません。
db.Model(&user).Association("Languages").Unscoped().Clear() |
- パーマネント削除: 関連レコードを物理的にデータベースから削除します。
// db.Unscoped().Model(&user) |
GORM のアソシエーションタグは、モデル間の関連がどのように処理されるかを指定するために使用されます。これらのタグは、外部キー、参照、制約など、関連に関する詳細を定義します。これらのタグを理解することは、関連を効果的に設定および管理するために不可欠です。
タグ | 説明 |
---|---|
foreignKey |
結合テーブル内の外部キーとして使用される、現在のモデルの列名を指定します。 |
references |
結合テーブルの外部キーがマップされる、参照テーブル内の列名を指定します。 |
polymorphic |
多態的なタイプ、通常はモデル名を定義します。 |
polymorphicValue |
多態的な値、通常はテーブル名を設定します。特に指定されていない場合。 |
many2many |
多対多リレーションシップで使用される結合テーブルの名前を付けます。 |
joinForeignKey |
現在のモデルのテーブルにマップし直す結合テーブル内の外部キー列を特定します。 |
joinReferences |
参照モデルのテーブルにリンクする結合テーブル内の外部キー列を示します。 |
constraint |
関連付けの OnUpdate 、OnDelete などのリレーショナル制約を指定します。 |