モデルの宣言

GORMは、Goの構造体をデータベースのテーブルにマッピングすることで、データベースとのやり取りを簡素化します。GORMでモデルを宣言する方法を理解することは、その全機能を活用するための基礎となります。

モデルの宣言

モデルは通常の構造体を使用して定義されます。これらの構造体には、Goの基本型、ポインタまたはこれらの型のエイリアス、あるいはカスタム型でさえ、`database/sql`パッケージのScannerインターフェースとValuerインターフェースを実装している限り、フィールドを含めることができます。

`User`モデルの次の例を考えてみましょう。

type User struct {
ID uint // Standard field for the primary key
Name string // A regular string field
Email *string // A pointer to a string, allowing for null values
Age uint8 // An unsigned 8-bit integer
Birthday *time.Time // A pointer to time.Time, can be null
MemberNumber sql.NullString // Uses sql.NullString to handle nullable strings
ActivatedAt sql.NullTime // Uses sql.NullTime for nullable time fields
CreatedAt time.Time // Automatically managed by GORM for creation time
UpdatedAt time.Time // Automatically managed by GORM for update time
}

このモデルでは、

  • `uint`、`string`、`uint8`のような基本データ型が直接使用されています。
  • `*string`や`*time.Time`のような型へのポインタは、NULL許容フィールドを示します。
  • `database/sql`パッケージの`sql.NullString`と`sql.NullTime`は、より詳細な制御を必要とするNULL許容フィールドに使用されます。
  • `CreatedAt`と`UpdatedAt`は、レコードが作成または更新されたときにGORMが自動的に現在の時刻を設定する特別なフィールドです。

GORMにおけるモデル宣言の基本機能に加えて、serializerタグによるシリアライズのサポートが重要です。この機能は、データベースにデータを格納および取得する方法の柔軟性を高めます。特に、カスタムシリアライズロジックが必要なフィールドに有効です。詳細な説明については、Serializerを参照してください。

規約

  1. **主キー**: GORMは、各モデルのデフォルトの主キーとして`ID`という名前のフィールドを使用します。

  2. **テーブル名**: デフォルトでは、GORMは構造体名を`snake_case`に変換し、テーブル名として複数形にします。たとえば、`User`構造体はデータベースでは`users`になります。

  3. **カラム名**: GORMは、データベースのカラム名として構造体フィールド名を自動的に`snake_case`に変換します。

  4. **タイムスタンプフィールド**: GORMは、`CreatedAt`と`UpdatedAt`という名前のフィールドを使用して、レコードの作成時刻と更新時刻を自動的に追跡します。

これらの規約に従うことで、記述する必要がある設定やコードの量を大幅に削減できます。ただし、GORMは柔軟性があり、デフォルトの規約が要件に合わない場合は、これらの設定をカスタマイズすることもできます。GORMの規約に関するドキュメントで、これらの規約のカスタマイズについて詳しく学ぶことができます。

`gorm.Model`

GORMは、一般的に使用されるフィールドを含む定義済み構造体`gorm.Model`を提供します。

// gorm.Model definition
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
  • **構造体への埋め込み**: これらのフィールドを自動的に含めるには、`gorm.Model`を構造体に直接埋め込むことができます。これは、異なるモデル間で一貫性を維持し、GORMの組み込み規約を活用するのに役立ちます。埋め込み構造体を参照してください。

  • 含まれるフィールド:

    • `ID`: 各レコードの一意の識別子(主キー)。
    • `CreatedAt`: レコードが作成されたときに現在の時刻に自動的に設定されます。
    • `UpdatedAt`: レコードが更新されるたびに現在の時刻に自動的に更新されます。
    • `DeletedAt`: 論理削除(レコードをデータベースから実際に削除することなく、削除済みとしてマークする)に使用されます。

高度な設定

フィールドレベルのパーミッション

エクスポートされたフィールドは、GORMでCRUDを実行する際にすべてのパーミッションを持ちます。GORMでは、タグを使用してフィールドレベルのパーミッションを変更できるため、フィールドを読み取り専用、書き込み専用、作成専用、更新専用、または無視するように設定できます。

**注意** 無視されたフィールドは、GORM Migratorを使用してテーブルを作成する際に作成されません。

type User struct {
Name string `gorm:"<-:create"` // allow read and create
Name string `gorm:"<-:update"` // allow read and update
Name string `gorm:"<-"` // allow read and write (create and update)
Name string `gorm:"<-:false"` // allow read, disable write permission
Name string `gorm:"->"` // readonly (disable write permission unless it configured)
Name string `gorm:"->;<-:create"` // allow read and create
Name string `gorm:"->:false;<-:create"` // createonly (disabled read from db)
Name string `gorm:"-"` // ignore this field when write and read with struct
Name string `gorm:"-:all"` // ignore this field when write, read and migrate with struct
Name string `gorm:"-:migration"` // ignore this field when migrate with struct
}

作成/更新時刻/Unix(ミリ/ナノ)秒の追跡

GORMは、慣例により`CreatedAt`、`UpdatedAt`を使用して作成/更新時刻を追跡します。GORMは、フィールドが定義されている場合、作成/更新時に現在の時刻を設定します。

異なる名前のフィールドを使用するには、`autoCreateTime`、`autoUpdateTime`タグでこれらのフィールドを設定できます。

時刻の代わりにUNIX(ミリ/ナノ)秒を保存する場合は、フィールドのデータ型を`time.Time`から`int`に変更するだけです。

type User struct {
CreatedAt time.Time // Set to current time if it is zero on creating
UpdatedAt int // Set to current unix seconds on updating or if it is zero on creating
Updated int64 `gorm:"autoUpdateTime:nano"` // Use unix nano seconds as updating time
Updated int64 `gorm:"autoUpdateTime:milli"`// Use unix milli seconds as updating time
Created int64 `gorm:"autoCreateTime"` // Use unix seconds as creating time
}

埋め込み構造体

匿名フィールドの場合、GORMはそのフィールドを親構造体に含めます。例:

type User struct {
gorm.Model
Name string
}
// equals
type User struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
Name string
}

通常の構造体フィールドの場合は、`embedded`タグを使用して埋め込むことができます。例:

type Author struct {
Name string
Email string
}

type Blog struct {
ID int
Author Author `gorm:"embedded"`
Upvotes int32
}
// equals
type Blog struct {
ID int64
Name string
Email string
Upvotes int32
}

また、`embeddedPrefix`タグを使用して、埋め込みフィールドのDB名にプレフィックスを追加することもできます。例:

type Blog struct {
ID int
Author Author `gorm:"embedded;embeddedPrefix:author_"`
Upvotes int32
}
// equals
type Blog struct {
ID int64
AuthorName string
AuthorEmail string
Upvotes int32
}

フィールドタグ

タグはモデルを宣言する際にオプションで使用できます。GORMは次のタグをサポートしています。
タグは大文字と小文字を区別しませんが、`camelCase`が推奨されます。

タグ名 説明
column カラムのDB名
type カラムのデータ型。すべてのデータベースで動作し、`not null`、`size`、`autoIncrement`…のような他のタグと一緒に使用できる、bool、int、uint、float、string、time、bytesなどの互換性のある汎用型を使用することが推奨されます。 `varbinary(8)`のような特定のデータベースデータ型もサポートされています。特定のデータベースデータ型を使用する場合は、`MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT`のように、完全なデータベースデータ型である必要があります。
serializer データをDBにシリアライズおよびデシリアライズする方法のシリアライザを指定します。例:`serializer:json/gob/unixtime`
size カラムデータのサイズ/長さを指定します。例:`size:256`
primaryKey カラムを主キーとして指定します。
unique カラムを一意として指定します。
default カラムのデフォルト値を指定します。
precision カラムの精度を指定します。
scale カラムのスケールを指定します。
not null カラムをNOT NULLとして指定します。
autoIncrement カラムを自動増分として指定します。
autoIncrementIncrement 自動増分ステップ。連続する列の値の間隔を制御します。
embedded フィールドを埋め込みます。
embeddedPrefix 埋め込みフィールドのカラム名プレフィックス。
autoCreateTime 作成時の現在の時刻を追跡します。`int`フィールドの場合、Unix秒を追跡します。`nano` / `milli`値を使用してUnixナノ/ミリ秒を追跡します。例:`autoCreateTime:nano`
autoUpdateTime 作成/更新時の現在の時刻を追跡します。`int`フィールドの場合、Unix秒を追跡します。`nano` / `milli`値を使用してUnixナノ/ミリ秒を追跡します。例:`autoUpdateTime:milli`
index オプション付きでインデックスを作成します。複数のフィールドに同じ名前を使用すると、複合インデックスが作成されます。詳細はインデックスを参照してください。
uniqueIndex `index`と同じですが、一意のインデックスを作成します。
check チェック制約を作成します。例:`check:age > 13`、制約を参照してください。
<- フィールドの書き込みパーミッションを設定します。`<-:create`は作成専用フィールド、`<-:update`は更新専用フィールド、`<-:false`は書き込みパーミッションなし、`<-`は作成および更新パーミッションです。
-> フィールドの読み取りパーミッションを設定します。`->:false`は読み取りパーミッションなしです。
- このフィールドを無視します。`-`は読み取り/書き込みパーミッションなし、`-:migration`は移行パーミッションなし、`-:all`は読み取り/書き込み/移行パーミッションなしです。
comment 移行時にフィールドにコメントを追加します。

アソシエーションタグ

GORMでは、アソシエーションの外部キー、制約、多対多テーブルをタグで設定できます。詳細はアソシエーションセクションを参照してください。

プラチナスポンサー

ゴールドスポンサー

プラチナスポンサー

ゴールドスポンサー