【Go】GORM v1.30 ジェネリクスAPIで型安全にレコードを削除する方法
はじめに
前回は、GORM v1.30で追加されたジェネリクスAPIで型安全にレコードを更新する方法について見ていきました。
今回は、同じくジェネリクスAPIを使って、型安全にレコードを削除する方法を見ていきます!
この記事でわかること
- 従来のレコード削除方法とジェネリクスAPIでの削除方法の違い
ジェネリクスAPIを使ったレコードの削除
ここでは、ジェネリクスAPIを使ったレコードの削除方法を、従来の実装と比較しながら見ていきましょう。
1. レコードの削除
従来のレコードの削除は、以下のように実装することができます。
// 削除に関わる部分のみ抜粋
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"not null"`
Birthday time.Time `gorm:"type:date"`
}
birthday, _ := time.Parse(time.DateOnly, "2025-09-05")
user := User{ID: 8, Name: "Bob", Birthday: birthday}
// 主キーを指定し削除
db.Delete(&user)
実行されるSQLは以下のようになります。
# 主キーを指定し削除
[3.236ms] [rows:1] DELETE FROM "users" WHERE "users"."id" = 8
GORMでは、gorm.DeletedAtのフィールドが構造体に含まれている場合、物理削除ではなく論理削除が実行されるようになります。
先ほどのコードにはgorm.DeletedAtのフィールドが存在しなかったためDELETEされましたが、存在する場合はUPDATEされます。
一方、ジェネリクスAPIを用いたレコードの削除は、以下のように実装することができます。
// 削除に関わる部分のみ抜粋
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"not null"`
Birthday time.Time `gorm:"type:date"`
DeletedAt gorm.DeletedAt // 追加
}
// 主キーを指定し論理削除
row, err := gorm.G[User](db).Where("id = ?", 7).Delete(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Println("Row Affected:", row) // 出力結果→Row Affected: 1
実行されるSQLは以下の通りです。
## 主キーを指定し論理削除
UPDATE "users" SET "deleted_at"='2025-09-16 22:37:30.89' WHERE id = 7 AND "users"."deleted_at" IS NULL
Deleteメソッドを使う際は、条件を指定しないとエラーになります。
Global Deleteを防ぐためのガードとなっているので、条件を指定するようにしましょう。
また、ジェネリクスAPIでのDeleteメソッドのシグネチャは以下の通りです。
func (c chainG[T]) Delete(ctx context.Context) (rowsAffected int, err error)
Deleteメソッドは、条件に合致するレコードを削除するメソッドです。
引数:
ctx: コンテキスト、処理のキャンセルやタイムアウトを制御するために使用
戻り値:
rowsAffected: 削除された行数、0の場合条件に合致するレコードが存在しないことを示す
err: 削除処理中に発生したエラー、正常に更新できた場合はnil
まとめ
今回は、GORM v1.30で追加されたジェネリクスAPIを使って、型安全にレコードを削除する方法を見ていきました。
基本的な実装方法は、従来のものと大きくは違わないように見受けられます。
次回は、「ジェネリクスAPIのJoinsとPreload」について見ていきます!
Discussion