gormのmany2manyはこうすると上手く行く
Go言語のgormというORマッパーを使った時のハマったところとその解決についてです。ほぼ自分用メモです。
尚、2021/06/23現在の最新バージョン gorm.io/gorm v1.21.11 を使用しています。
駄目だった実装
https://gorm.io/ja_JP/docs/many_to_many.html
gormのドキュメントを見ながら書いた最初のコードはこんな感じでした。
type Person struct {
PersonId string `json:"person_id" gorm:"primaryKey;autoIncrement:false"`
Languages []Language `gorm:"many2many:person_languages;"`
}
type Language struct {
LanguageCode string `json:"language_code" gorm:"primaryKey;autoIncrement:false"`
Name string `json:"name"`
}
type PersonLanguages struct {
PersonId string `json:"person_id" gorm:"primaryKey;autoIncrement:false"`
LanguageCode string `json:"language_code" gorm:"primaryKey;autoIncrement:false"`
}
ここから、personを取得した時に紐づくlanguagesを一気に取得したい、というのがもともとの動機です。
しかし、
result := DB.First(&person)
とした時、personに紐付いている中間テーブルを介して取得できるlanguagesがあるはずなのに、 len(person.Languages)
はゼロ。
gormのドキュメントを見ただけでは、なぜうまく行かないのかわからず。
上手く行った実装
- Preloadする
- キーとなるカラム名からテーブル名prefixを取る
この2点が必要でした。
1. Preloadする
DB.Preload("Languages").First(&person)
参照
https://note.com/note_fumi/n/n29a8d64ce46d
2. キーとなるカラム名からテーブル名prefixを取る
PersonのPersonIdをIdに、
LanguageのLanguageCodeをCodeにするべきでした。
type Person struct {
Id string `json:"id" gorm:"primaryKey;autoIncrement:false"`
Languages []Language `gorm:"many2many:person_languages;"`
}
type Language struct {
Code string `json:"code" gorm:"primaryKey;autoIncrement:false"`
Name string `json:"name"`
}
こういうことです。当然ですが、マイグレーションからやり直す必要があります。
こうすると、
DB.Preload("Languages").First(&person)
で person.Languages
でpersonに紐づくLanguagesがちゃんと取得できます。
ドキュメントにこのような記載が無かったので少し混乱しましたが、自分の仮説が当たっていたようでした。(すごく熟読したわけじゃないので、実は書いてあるかも?)
調査していないですが、gormの挙動から想像するに、has manyでも同じことが起きそうです。
※元のコードから脚色を加えたものを掲載しているため、このままでは上手く動かない可能性があります。
記事を書き慣れてないので、読みづらかったらすみません。
Author And Source
この問題について(gormのmany2manyはこうすると上手く行く), 我々は、より多くの情報をここで見つけました https://qiita.com/ryo0/items/0d5450ca221534b7c91d著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .