関連付け
リレーションシップをモデル化します
「関連付け」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
リレーションシップのモデル化
GORMのアソシエーションは、テーブル間のリレーションシップを構造体のフィールドに対応付けます。種類は、has one、has many、belongs to、many to manyの4つです。
- 外部キーを構造体のフィールドとして表現します
- 関連データを自動的に読み込みます
- 関連レコードをまとめて作成します
Has Many
ユーザーは複数の投稿を持ちます。親は子のスライスを保持し、子は親を参照する外部キーを保持します。
type User struct {
gorm.Model
Name string
Posts []Post
}
type Post struct {
gorm.Model
Title string
UserID uint
}Belongs To
子の視点では、投稿はユーザーに属します。これを表現するには、User フィールドと UserID 外部キーを追加します。
type Post struct {
gorm.Model
Title string
UserID uint
User User
}Has One
has-oneはhas-manyに似ていますが、関連するレコードが1つだけです。たとえば、ユーザーが1つのプロフィールを持つ場合です。子が外部キーを保持します。
type User struct {
gorm.Model
Profile Profile
}
type Profile struct {
gorm.Model
UserID uint
Bio string
}Many To Many
ユーザーとロールは、結合テーブルを介して多対多で関連します。many2many タグでその結合テーブルを指定します。Rolesフィールドの後ろにバッククォートで gorm:"many2many:user_roles;" と記述します。
type User struct {
gorm.Model
// Roles field tag: gorm:"many2many:user_roles;"
Roles []Role
}
type Role struct {
gorm.Model
Name string
}Preload
デフォルトでは、関連データは読み込まれません。Preload を使うと、GORMが別のクエリでアソシエーションを取得するため、手動で別途検索する必要がなくなります。
var user User
db.Preload("Posts").First(&user, 1)
fmt.Println(len(user.Posts))ネストしたPreload
ドット区切りのパスを使うと、複数の階層にわたってpreloadできます。1回のメソッドチェーンで、ユーザーの投稿と各投稿のコメントを読み込めます。
db.Preload("Posts.Comments").First(&user, 1)実行可能なアソシエーションのシミュレーション
GORMにはデータベースが必要です。そのため、この実行可能な例では、メモリ上のスライスを使ってhas-manyのリレーションシップとpreloadをモデル化します。
package main
import "fmt"
type Post struct {
ID int
UserID int
Title string
}
type User struct {
ID int
Name string
Posts []Post
}
func preload(u *User, all []Post) {
for _, p := range all {
if p.UserID == u.ID {
u.Posts = append(u.Posts, p)
}
}
}
func main() {
u := User{ID: 1, Name: "Ada"}
all := []Post{{1, 1, "Hello"}, {2, 1, "World"}, {3, 2, "Other"}}
preload(&u, all)
fmt.Printf("%s has %d posts\n", u.Name, len(u.Posts))
}アソシエーションを伴う作成
Create の前にスライスフィールドを設定しておくと、GORMが親と子をまとめて挿入し、外部キーを自動的に設定します。
user := User{Name: "Ada", Posts: []Post{{Title: "Hi"}}}
db.Create(&user)N+1問題
親をループして反復ごとに子を検索すると、親ごとに1回ずつクエリが発行され、N+1問題が発生します。Preload を使うと、関連データの取得を1回の追加クエリにまとめて解決できます。
アソシエーションモード
Association APIを使うと、外部キーを手動で扱わずに、関連レコードの追加、置換、削除、クリアを行えます。たとえば db.Model(&user).Association("Posts").Append(&post) のように記述します。
理解度チェック
アソシエーションに関する知識を確認しましょう。
まとめ
アソシエーションについて学びました。
- has one、has many、belongs to、many2manyでモデル間のリレーションシップを表します
- 外部キーはUserIDのような構造体フィールドです
- Preloadはアソシエーションを読み込み、N+1問題を避けます
- 子を持つ親を作成すると、外部キーが設定されます
- アソシエーションモードでリレーションを追加、置換、クリアできます
よくある質問
「関連付け」レッスンは無料ですか?
はい。「関連付け」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「関連付け」で何を学びますか?
リレーションシップをモデル化します ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「関連付け」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。