LoginSignup
0
0

More than 1 year has passed since last update.

構造体の埋め込みを GORM で利用すると便利

Posted at

構造体の埋め込み

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 関数の結果を受け取れるような構造体を簡単に定義できることがわかります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0