構造体の埋め込み
type A struct{}
func (A) Execute() { println("A") }
type C struct { A }
func Test(t *testing.T) {
c := C{}
c.Execute()
}
上記のコードは正しく動作します。
このように、構造体を別の構造体に埋め込むことを Struct Embedding と呼びます。
GORM での利用
GORM では、構造体からテーブル名を得る際に、構造体の TableName
メソッドが使われます。
たとえば次のコードを書いたとき、GORM は a
というテーブル名を得ます。
type A struct{}
func (A) TableName() string { return "a" }
Struct Embedding により、以下の B
構造体は、外から見ると TableName
メソッドを持つかのように見えます。
type A struct{}
type B struct{ A }
func (A) TableName() string { return "a" }
よって、以下のコードは、a
テーブルのすべての行を取得することを意味します。
var rows []B
db.Find(&rows)
具体例 : Window 関数との併用
各生徒のテストの点数が格納されているテーブルがあるとします。
そして、成績の良い順に順位を割り振りたいとします。
テストの点数のテーブルを表す構造体の定義は以下です。
type TestScore struct {
ID uint
Name string
Score uint
}
func (TestScore) TableName() string {
return "test_score"
}
このとき、次のように書くことで、順位を含めた結果を得ることができます。
type Result struct {
TestScore
Rank uint `gorm:"column:rank_"`
}
var results []Result
db.Select("*, RANK() OVER (ORDER BY score DESC) AS rank_").Find(&results)
Struct Embedding を使うことで、Window 関数の結果を受け取れるような構造体を簡単に定義できることがわかります。