2019年10月16日

プログラミング

Railsでparanoiaを使って論理削除を実装する

目次

  1. はじめに
  2. 物理削除と論理削除
  3. paranoia の導入
  4. paranoia の使い方
  5. まとめ

はじめに

はじめまして!エンジニアの こぼり と申します。今回はRailsでparanoiaを使った論理削除の実装について説明します!
paranoiaのGitHubを参照して書きました!

環境

  • Ruby: 2.6.3
  • Rails: 6.0.0
  • paranoia: 2.4.2

物理削除と論理削除

物理削除とはDB上からデータを削除すること指し、一方で論理削除とは表面上データを削除したようにみせるが、DB上ではデータを残しておくことをいいます。

paranoia の導入

gemのインストール

Gemfileに以下のように記述し、

 gem 'paranoia'

bundleコマンドでgemをインストールします。

 $ bundle install

カラムの追加

以下のコマンドを実行すると…

 $ rails g migration AddDeletedAtToUsers deleted_at:datetime:index

マイグレーションファイルが生成されます。
今回はUserモデルを例に説明を進めていきます。

 class AddDeletedAtToUsers < ActiveRecord::Migration[6.0]
def change
add_column :users, :deleted_at, :datetime
add_index :users, :deleted_at
end
end

マイグレーションを実行します。

 $ rails db:migrate

acts_as_paranoidの記述

論理削除を適用したいテーブルのモデルファイルにacts_as_paranoidを記述します。

 class User < ApplicationRecord
acts_as_paranoid
end

これで準備はOKです!

paranoia の使い方

基本的な動き

railsコンソールに入ってみましょう!

 $ rails c

ユーザを2人作成し確認します。

> User.create(name: "test1")
> User.create(name: "test2")
> User.all

ユーザが2人作成されました。

 => User id: 1, name: "test1", created_at: "2019-09-04 08:25:06", updated_at: "2019-09-04 08:35:53", deleted_at: nil
User id: 2, name: "test2", created_at: "2019-09-04 08:36:10", updated_at: "2019-09-04 08:36:10", deleted_at: nil

ID が1 のユーザデータを取得して削除を実行します。

 > user = User.find(1)
> user.destroy
> User.all

再びユーザを取得してみるとID:1 のユーザが削除されていることがわかります。

 => User id: 2, name: "test2", created_at: "2019-09-04 08:36:10", updated_at: "2019-09-04 08:36:10", deleted_at: nil

実際のDBを見てみるとDB上はデータが残ってます。この状態を「論理削除」といいます。
さきほどdeleteを実行したid:1のユーザのレコードを見てましょう。今回新しく追加した「deleted_at カラム」にdeleteを実行した日時が入っています。paranoiaはこのカラムを元に削除の判定をしていることがわかります。
スクリーンショット 2019-09-04 17.46.51.png (23.4 kB)

元に戻したい

クラスとインスタンスそれぞれから論理削除したデータを元に戻すことができます。
コンソールから下記コマンドを実行するとdelete_at カラムがnullで更新され、対象データが元に戻ります!

 > user.restore

クラスから実行する場合にはIDを指定して実行します。

 > User.restore(1)

削除分も含めたデータ取得

以下のコマンドで論理削除されたデータも含めたデータ検索をすることができます。

 > User.with_deleted

削除したデータのみ取得

論理削除されたデータのみを取得することもできます。
たとえば、「削除済み一覧」を作りたい場合に活用できそうです。

 > User.only_deleted

削除したデータを除いて取得

下記コマンドでは、論理削除されたデータを除いて取得することができ、
User.allと同じ結果が得られます。

 > User.without_deleted

どんな時に使う?

対象のモデルファイルにacts_as_paranoid without_default_scope: trueと記述した場合、データ検索のデフォルトが論理削除も含めた検索に設定されます。この場合にUser.without_deletedを用いた論理削除したデータを除いた検索が活用できます。

物理削除したい!

下記コマンドでDB上から完全に削除することができます。
元に戻すことができないため使う際には十分に注意が必要です。

 > user.really_destroy!

まとめ

論理削除を実装するgem、paranoia の使い方を見てきました。
データを削除したいけどリストアできる状態にしておきたい時に最適なgemです!
使い方は簡単だと思いますので、ぜひ使ってみてください!

0

0

AUTHOR

kobori

こぼり ともろう エンジニア

サーバーサイドエンジニア。SIerを経て2019年7月に入社。日々学習しながらRuby on Railsを使った開発を行っています。

アプリでもっと便利に!気になる記事をチェック!

記事のお気に入り登録やランキングが表示される昨日に対応!毎日の情報収集や調べ物にもっと身近なメディアになりました。

palanでは一緒に働く仲間を募集しています

正社員や業務委託、アルバイトやインターンなど雇用形態にこだわらず、
ベテランの方から業界未経験の方まで様々なかたのお力をお借りしたいと考えております。

話を聞いてみたい

運営メンバー

eishis

Eishi Saito 総務

SIerやスタートアップ、フリーランスを経て2016年11月にeishis, Inc.を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。

sasakki デザイナー

アメリカの大学を卒業後、日本、シンガポールでデザイナーとして活動。

しまだ

しまだ デザイナー

WebAR/VRのデザインと3DCG制作がメインです。 肩書きは「アニメ案件に関わりたいデザイナー」。

Miu マーケター

ドイツでWEBマーケティングしています。

しんのき エンジニア

新しい技術が好きなWebエンジニアです。 元々インフラやPHPをやっていたのですが、最近はReact NativeとFirebaseを使って頑張ってます。

yamakawa

やまかわたかし デザイナー

フロントエンドデザイナー。デザイン・HTML/CSSマークアップ・JSアニメーション実装を担当しています。

furuya エンジニア

サーバーサイド、フロントエンド、Unityと色々手を出してる雑食系エンジニア。ReactNativeが最近のマイブーム。

Sayaka Osanai デザイナー

Sketchだいすきプロダクトデザイナー。シンプルだけどちょっとかわいいデザインが得意。 好きな食べものは生ハムとお寿司とカレーです。

はらた

はらた エンジニア

サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

うえまつゆい エンジニア

サーバーサイドエンジニアからフロントエンドエンジニアになりました。主にReact Nativeでのアプリ開発をしています。

kobori

こぼり ともろう エンジニア

サーバーサイドエンジニア。SIerを経て2019年7月に入社。日々学習しながらRuby on Railsを使った開発を行っています。

sasai

ささい エンジニア

フロントエンドエンジニア WebGLとReactが強みと言えるように頑張ってます。

CONTACT PAGE TOP