メインコンテンツへスキップ
バージョン: v6 - 安定版

パラノイド

Sequelizeは、パラノイドテーブルの概念をサポートしています。パラノイドテーブルとは、レコードの削除を指示されたときに、実際には削除しないテーブルのことです。代わりに、deletedAtという特別な列に、削除リクエストのタイムスタンプが設定されます。

これは、パラノイドテーブルが、ハード削除ではなく、レコードのソフト削除を実行することを意味します。

モデルをパラノイドとして定義する

モデルをパラノイドにするには、モデル定義にparanoid: trueオプションを渡す必要があります。パラノイドはタイムスタンプが動作するために必要です(つまり、timestamps: falseも渡すと動作しません)。

また、デフォルトの列名(deletedAt)を別のものに変更することもできます。

class Post extends Model {}
Post.init(
{
/* attributes here */
},
{
sequelize,
paranoid: true,

// If you want to give a custom name to the deletedAt column
deletedAt: 'destroyTime',
},
);

削除

destroyメソッドを呼び出すと、ソフト削除が行われます。

await Post.destroy({
where: {
id: 1,
},
});
// UPDATE "posts" SET "deletedAt"=[timestamp] WHERE "deletedAt" IS NULL AND "id" = 1

モデルがパラノイドの場合、本当にハード削除したい場合は、force: trueオプションを使用して強制できます。

await Post.destroy({
where: {
id: 1,
},
force: true,
});
// DELETE FROM "posts" WHERE "id" = 1

上記の例では、静的destroyメソッド(Post.destroy)を例として使用しましたが、インスタンスメソッドでもすべて同じように動作します。

const post = await Post.create({ title: 'test' });
console.log(post instanceof Post); // true
await post.destroy(); // Would just set the `deletedAt` flag
await post.destroy({ force: true }); // Would really delete the record

復元

ソフト削除されたレコードを復元するには、静的バージョンとインスタンスバージョンの両方にあるrestoreメソッドを使用できます。

// Example showing the instance `restore` method
// We create a post, soft-delete it and then restore it back
const post = await Post.create({ title: 'test' });
console.log(post instanceof Post); // true
await post.destroy();
console.log('soft-deleted!');
await post.restore();
console.log('restored!');

// Example showing the static `restore` method.
// Restoring every soft-deleted post with more than 100 likes
await Post.restore({
where: {
likes: {
[Op.gt]: 100,
},
},
});

他のクエリでの動作

Sequelizeによって実行されるすべてのクエリは、ソフト削除されたレコードを自動的に無視します(もちろん、rawクエリは除きます)。

これは、たとえば、findAllメソッドがソフト削除されたレコードを認識せず、削除されていないレコードのみをフェッチすることを意味します。

ソフト削除されたレコードのプライマリキーを指定してfindByPkを呼び出すだけでも、そのレコードが存在しないかのように、結果はnullになります。

本当にクエリでソフト削除されたレコードを表示させたい場合は、クエリメソッドにparanoid: falseオプションを渡すことができます。例えば

await Post.findByPk(123); // This will return `null` if the record of id 123 is soft-deleted
await Post.findByPk(123, { paranoid: false }); // This will retrieve the record

await Post.findAll({
where: { foo: 'bar' },
}); // This will not retrieve soft-deleted records

await Post.findAll({
where: { foo: 'bar' },
paranoid: false,
}); // This will also retrieve soft-deleted records