はじめに
マルチテナントアプリケーションでは、複数の顧客(テナント)が同じアプリケーションを利用するため、データの分離が必要です。
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
モデルに属する場合、Comment
もtenant_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
これにより、Comment
はPost
を通じてテナントスコープを継承し、適切にフィルタリングされます。
マルチテナントデータベースの設定
データベーススキーマは、テナントごとに適切な外部キー制約を持つように設計されます。例えば、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を活用して、セキュアでスケーラブルなマルチテナントアプリケーションを構築してみてください。