0
0

【Golang】カラムにGormのDeleted_atが含まれる場合のレコード取得について

Posted at

論理削除を実装するために、gorm.DeletedAtを使用した場合、レコードの取得のクエリが論理削除されたデータを取得しないように自動的に切り替わる。
場合によって、論理削除したレコードも取得したことがあるため、論理削除したレコードを取得する方法についても備忘録として残す。

gorm.DeletedAtカラムがある場合のオブジェクト取得のクエリ

以下は公式ドキュメントのサンプルを流用
https://gorm.io/ja_JP/docs/query.html

type User struct {
  ID           string `gorm:"primarykey;size:16"`
  Name         string `gorm:"size:24"`
  DeletedAt    gorm.DeletedAt `gorm:"index"` // Gormの特定のフィールドタイプの使用
}

var user = User{ID: 15}
db.First(&user) // 論理削除を実装している構造体でFirst()メソッドを実行
//  SELECT * FROM `users` WHERE `users`.`id` = '15' AND `users`.`deleted_at` IS NULL ORDER BY `users`.`id` LIMIT 1

注目して欲しいのが、コメントアウトされている生成されるクエリである。
以下は見やすいように整形したもの。

SELECT * 
FROM `users` 
WHERE `users`.`id` = '15' AND 
      `users`.`deleted_at` IS NULL // このwhere句に注目
ORDER BY `users`.`id` 
LIMIT 1

論理削除が含まれる構造体に対するクエリにはwhere句の中に「deleted_at IS NULL」の条件が含まれている。
つまり、デフォルトでdeleted_atカラムがNULL以外のレコードが条件となっている。

通常であれば、論理削除されたものは取得しなくてもよいため、Gormは親切なメソッドを作成してくれている。

論理削除されたレコードを取得する。「Unscoped()メソッド」

仕様や要件によっては論理削除したレコードも取得したことがある。
この論理削除されたレコードを取得する方法も公式に載っているため、紹介する。
https://gorm.io/ja_JP/docs/delete.html

db.Unscoped().Where("age = 20").Find(&users)
// SELECT * FROM users WHERE age = 20;

論理削除されたレコードは「Unscoped()メソッド」を使用することで取得することができる。

論理削除のレコードを取得しないデフォルトのクエリを打ち消すサンプルコード

type User struct {
  ID           string `gorm:"primarykey;size:16"`
  Name         string `gorm:"size:24"`
  DeletedAt    gorm.DeletedAt `gorm:"index"` // Gormの特定のフィールドタイプの使用
}

var user = User{ID: 15}

db.Unscoped().First(&user)

通常のgormを使用したコードの前にUnscoped()を追加するだけ。

まとめ

Gormでは論理削除の実装及びそれを考慮したレコードの取得が簡単に行える。
ただし、論理削除が含まれる構造体へのGormのデフォルトのクエリが変化するため、注意が必要。
論理削除されたレコードを取得したい場合は「Unscoped()メソッド」を使用すること。

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