【Rails】Paranoiaを使用した論理削除(ソフトデリート)

はじめに

Paranoiaは、Railsアプリケーションで論理削除(ソフトデリート)を実現するためのGemです。

論理削除は、データベースのレコードを物理的に削除するのではなく、削除フラグを設定することで「削除済み」とみなす方法です。これにより、削除されたレコードを後から復元することが可能となり、データの整合性と安全性が向上します。

この記事では、Paranoiaの概要と、Railsでの使用方法について解説します。

Paranoiaについて

Paranoiaは、以下の機能を提供します。

  • 論理削除:レコードを物理削除する代わりに、deleted_atカラムにタイムスタンプを記録する
  • 自動スコープ:デフォルトで、論理削除されていないレコードのみをクエリに含める
  • 復元:論理削除されたレコードは簡単に復元可能

使用方法

インストール

まず、GemfileにParanoiaを追加し、bundle installを実行してインストールします。

Gemfile

gem 'paranoia', '~> 2.4'

モデルの設定

Paranoiaを使用するためには、モデルでParanoiaを有効にする必要があります。以下は、ArticleモデルにParanoiaを設定する例です。

app/models/article.rb

class Article < ApplicationRecord
  acts_as_paranoid

  # その他のモデルの設定
end

マイグレーションの追加

Paranoiaは論理削除のためにdeleted_atカラムを必要とします。次に、deleted_atカラムを追加するためのマイグレーションを作成します。

% rails generate migration AddDeletedAtToArticles deleted_at:datetime:index

生成されたマイグレーションファイルを以下のように編集します。

db/migrate/yyyymmddhhmmss_add_deleted_at_to_articles.rb

class AddDeletedAtToArticles < ActiveRecord::Migration[7.0]
  def change
    add_column :articles, :deleted_at, :datetime
    add_index :articles, :deleted_at
  end
end

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

% rails db:migrate

基本的な使い方

Paranoiaを有効にしたモデルでの基本的な操作方法を以下に示します。

レコードの論理削除

article = Article.find(1)
article.destroy
# => レコードは物理削除されず、deleted_atが設定される

削除済みレコードのスコープ

articles = Article.all
# => 削除されていないレコードのみが返される

削除済みレコードを含むクエリ

all_articles = Article.with_deleted
# => 削除済みレコードも含んだレコードが返される

削除済みレコードの取得

deleted_articles = Article.only_deleted
# => 削除済みレコードのみが返される

削除済みレコードの復元

article = Article.only_deleted.find(1)
article.restore
# => deleted_atがnilに設定され、レコードが復元される

実践的な例

例えば、ブログで記事を管理する場合、Paranoiaを使用して記事を論理削除し、必要に応じて復元することができます。

モデルの設定

app/models/article.rb

class Article < ApplicationRecord
  acts_as_paranoid

  validates :title, presence: true
  validates :content, presence: true
end

コントローラーの設定

app/constollers/articles_controller.rb

class ArticlesController < ApplicationController
  def index
    @articles = Article.all
  end

  def show
    @article = Article.find(params[:id])
  end

  def new
    @article = Article.new
  end

  def create
    @article = Article.new(article_params)
    if @article.save
      redirect_to @article, notice: '記事が作成されました。'
    else
      render :new
    end
  end

  def edit
    @article = Article.find(params[:id])
  end

  def update
    @article = Article.find(params[:id])
    if @article.update(article_params)
      redirect_to @article, notice: '記事が更新されました。'
    else
      render :edit
    end
  end

  def destroy
    @article = Article.find(params[:id])
    @article.destroy
    redirect_to articles_url, notice: '記事が削除されました。'
  end

  private

  def article_params
    params.require(:article).permit(:title, :content)
  end
end

ビューの設定

削除済みの記事を表示するためのリンクを追加できます。

app/views/articles/index.html.erb

<% @articles.each do |article| %>
  <h2><%= link_to article.title, article %></h2>
  <p><%= article.content %></p>
  <%= link_to '編集', edit_article_path(article) %> |
  <%= link_to '削除', article, method: :delete, data: { confirm: '本当に削除しますか?' } %>
<% end %>

削除済みの記事を一覧表示し、復元するためのビューを追加します。

app/views/articles/index.html.erb

<h1>削除済みの記事</h1>

<% @deleted_articles.each do |article| %>
  <h2><%= article.title %></h2>
  <p><%= article.content %></p>
  <%= link_to '復元', restore_article_path(article), method: :patch %>
<% end %>

まとめ

Paranoiaは、Railsアプリケーションにおいて論理削除を簡単に実装するためのGemです。データを物理的に削除することなく削除済みとして扱うことで、データの復元が容易になります。

この記事では、Paranoiaの概要と使用方法を紹介しました。実際のプロジェクトで論理削除が必要な場合には、Paranoiaを活用してデータの安全性と柔軟性を確保しましょう。

関連記事

【Rails】activerecord-multi-tenantを使用したマルチテナントアプリケーションの作成
# はじめに マルチテナントアプリケーションでは、複数の顧客(テナント)が同じアプリケーションを利用するため、データの分離が必要です。 activerecord-multi-tenantは、このようなマルチテナント環境をサポートするための便 [...]
2024年7月18日 16:50
【Rails】RubyとRailsにおけるattr_reader, attr_writer, attr_accessorの概念と使用方法
# はじめに RubyとRailsの開発において、`attr_reader`,`attr_writer`,`attr_accessor`は非常に便利なメソッドです。これらは、クラス内でインスタンス変数に対するゲッターおよびセッターメソッドを簡単に [...]
2024年7月17日 18:11
【Rails】RubyとRailsにおけるyieldの概念と使用方法
# はじめに RubyとRailsにおける`yield`は、メソッドやテンプレートの中で動的にコードブロックを実行する能力を提供し、これによってコードの再利用性と拡張性が大幅に向上します。本記事では、RubyとRailsにおける`yield`の概 [...]
2024年7月17日 13:15
【Rails】AASMを使用してオブジェクトの状態遷移を効率的に管理
# はじめに Railsアプリケーションにおいて、オブジェクトの状態管理は重要な課題の一つです。AASM (Acts As State Machine) gemは、複雑な状態遷移を効率的に管理します。本記事では、AASMの基本的な使い方を解説して [...]
2024年7月16日 18:00
【Rails】RSpec + Swagger + rswagでアプリケーションのAPIをテストおよびドキュメント化する方法
# はじめに Railsアプリケーションの開発において、APIのテストとドキュメント化は重要な要素です。 RSpecはテストフレームワークとして広く利用されており、SwaggerはAPIの設計とドキュメント化を支援します。これらを統合するr [...]
2024年7月16日 14:27
【Rails】mailcatcherを使用して開発環境でメール送信をテストする方法
# はじめに mailcatcherは、開発環境でのメール送信をキャプチャするためのツールです。ローカルで送信されたメールをブラウザ上で簡単に確認できるようにします。mailcatcherをRailsアプリケーションで使用する方法について説明しま [...]
2024年7月15日 16:37
【Rails】impressionistを使用してページビューやクリック数を追跡する方法
# はじめに impressionist Gemを使用してRailsアプリケーションでページビューやクリック数を追跡する方法について説明します。 # 実装方法 ## impressionist Gemのインストール まず、impre [...]
2024年7月15日 14:18
【Rails】meta-tagsを使用したメタタグの管理
# はじめに RailsアプリケーションでSEO対策を行うために、meta-tags Gemを使用してメタタグを管理する方法について説明します。 # メタタグの管理 ## meta-tags Gemのインストール まず、meta-t [...]
2024年7月15日 13:47