nakaoka3の技術ブログ

2023年中に52本なにか書きます

GORM で論理削除済みのレコードを取得するにはUnscopedメソッドをつける

Go言語でGORMというORMライブラリを使っています。GORM で論理削除済みのレコードを取得するには Unsocpedメソッドを使います。実行されるSQLを確認するには Debug メソッドを使います。

GORMとは

GORMとは、Go言語のORM(Object Relational Mapping)ライブラリです。

gorm.io

以下のようにTake (またはFirst Last)メソッドをつかって、レコードを取得できます。

db.Take(&user)

実行されたSQLを確認するには

実行されたSQLを確認するには Debug メソッドを使います。標準出力に実行されたSQLが出力されます。

db.Debug().Take(&user)
// SELECT * FROM users LIMIT 1;

ドキュメントを全部読んで理解するのは大変なので、GORM が何をしているかわからなくなったら Debug をつかってSQLを見るのが早いです。

論理削除されたレコードを取得するには

GORMでは Deleteメソッドでレコードを削除できますが、モデルにDeletedAtフィールドが含まれると論理削除されるようになります。

(gorm.Modelにも含まれている) gorm.DeletedAt フィールドがモデルに含まれている場合、そのモデルは自動的に論理削除されるようになります。 https://gorm.io/ja_JP/docs/delete.html

その場合、Take などで論理削除されたレコードを取得しようとしても、WHERE deleted_at IS NOT NULL のような条件が追加されて、取得することはできません。

論理削除されたレコードを取得するには Unscopedメソッドを使います。

db.Unscoped().Where("age = 20").Find(&users)

レコードの削除 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

同様にUnscopedを使うことで、レコードを物理削除できます。

Scopeとは、共通で使用するロジックを再利用するための仕組みです。GORMだけの概念というわけではなく、他のORMライブラリでも使われる概念です。

Scopes | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

まとめ

アプリケーションのなかでORMを使って論理削除されたレコードを取得したくなるというのは、何か設計に問題があるような気がしますが、一応可能ではあるようです。それはともかく、GORMのScope自体は便利そうなので使っていきたいです。