【Rails】activerecord-multi-tenantを使用したマルチテナントアプリケーションの作成

はじめに

マルチテナントアプリケーションでは、複数の顧客(テナント)が同じアプリケーションを利用するため、データの分離が必要です。

activerecord-multi-tenantは、このようなマルチテナント環境をサポートするための便利なGemです。これにより、テナントごとにデータを分離し、セキュリティとパフォーマンスを向上させることができます。

activerecord-multi-tenantについて

activerecord-multi-tenantは、ActiveRecordにマルチテナンシー機能を追加するためのGemです。このGemを使用すると、モデルにテナントを関連付け、各テナントのデータが他のテナントと混在しないように管理できます。主な特徴は以下の通りです。

  • テナントのスコープ:テナントごとにデータを自動的にフィルタリング
  • マルチテナント対応モデル:特定のモデルをマルチテナント対応に設定
  • シンプルな設定:少ないコード変更でマルチテナンシーを実現

使用方法

インストール

まず、Gemfileにactiverecord-multi-tenantを追加し、bundle installを実行します。

Gemfile

gem 'activerecord-multi-tenant'

テナントモデルの作成

テナントモデルを作成します。ここでは、Tenantモデルを使用します。

% rails generate model Tenant name:string
% rails db:migrate

テナント対応モデルの作成

テナントに関連付けられるモデルを作成します。例えば、Postモデルをテナント対応にします。

% rails generate model Post title:string content:text tenant:references
% rails db:migrate

Postモデルにactiverecord-multi-tenantを設定します。

app/models/post.rb

class Post < ApplicationRecord
  multi_tenant :tenant

  belongs_to :tenant
end

この設定により、Postモデルはtenant_idを持つことが前提となり、テナントごとにデータがスコープされます。

テナントスコープの設定

アプリケーションコントローラーで現在のテナントを設定します。例えば、サブドメインベースのテナント設定を行う場合は以下のように実装します。

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  set_current_tenant_through_filter
  before_action :set_tenant

  private

  def set_tenant
    tenant_name = request.subdomain
    @current_tenant = Tenant.find_by!(name: tenant_name)
    set_current_tenant(@current_tenant)
  end
end

set_current_tenantメソッドは、現在のテナントをグローバル変数に設定し、モデルでのデータアクセス時に自動的に適用されます。

データ操作

テナントスコープが設定されると、Postモデルの操作は自動的に現在のテナントにスコープされます。

# 現在のテナントの投稿を作成
Post.create(title: 'New Post', content: 'This is a new post')

# 現在のテナントの投稿を取得
@posts = Post.all

テナントの継承

モデル間での関連付けもテナントスコープを考慮します。例えば、CommentモデルがPostモデルに属する場合、Commenttenant_idを持ちます。

app/models/comment.rb

class Comment < ApplicationRecord
  multi_tenant :tenant

  belongs_to :post
  belongs_to :tenant
end

app/models/post.rb

class Post < ApplicationRecord
  multi_tenant :tenant

  has_many :comments
  belongs_to :tenant
end

これにより、CommentPostを通じてテナントスコープを継承し、適切にフィルタリングされます。

マルチテナントデータベースの設定

データベーススキーマは、テナントごとに適切な外部キー制約を持つように設計されます。例えば、postsテーブルにはtenant_idが必要です。

db/migrate/yyyymmddhhmmss_create_posts.rb

class CreatePosts < ActiveRecord::Migration[6.0]
  def change
    create_table :posts do |t|
      t.string :title
      t.text :content
      t.references :tenant, null: false, foreign_key: true

      t.timestamps
    end
  end
end

このマイグレーションにより、postsテーブルにtenant_idカラムが追加され、外部キー制約が適用されます。

まとめ

activerecord-multi-tenantを使用することで、Railsアプリケーションにマルチテナンシー機能を簡単に追加できます。これにより、複数の顧客データを安全かつ効率的に管理できるようになります。

テナントモデルの設定から、テナントスコープの適用まで、わずかなコード変更で実現できるため、開発者にとって非常に有用なツールです。ぜひ、このGemを活用して、セキュアでスケーラブルなマルチテナントアプリケーションを構築してみてください。

関連記事

【Rails】Paranoiaを使用した論理削除(ソフトデリート)
# はじめに Paranoiaは、Railsアプリケーションで論理削除(ソフトデリート)を実現するためのGemです。 論理削除は、データベースのレコードを物理的に削除するのではなく、削除フラグを設定することで「削除済み」とみなす方法です。こ [...]
2024年7月20日 21:33
【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