LoginSignup
4
1

More than 3 years have passed since last update.

マルチテナンシー(Multitenancy)を簡単に実現できるgem「acts_as_tenant」を実装

Last updated at Posted at 2019-07-19

背景

:relaxed:仕訳記録用の会計ソフトを開発しています。ユーザのサインアップ、検証、ログイン、ログアウト機能は既にできています。
:frowning2:ただし、例えばユーザAが登録した仕訳が、新しくサインアップしてログインしたユーザBに漏れなく見られてしまいます。つまり、全てのデータは全員共有という状態です。
:point_right:望ましいのは、ユーザAが登録した仕訳がユーザAのみに見られ、ユーザBがサインアップしてログインすると、またきれいな環境になり、ユーザBがユーザBのみ見られる仕訳を登録できるようになるということです。
ただし、一部の汎用勘定科目はAもBも見れます。
また、アプリのURLは変わらないです。AもBも同じURLで同じシステムをログインします。

いろいろ調べた結果

:one:希望な機能は「マルチテナンシー」(Multitenancy)と呼ばれます。
:two:幸いなのは、Railsの中に既にいくつかのGemがありました。苦労せず実現できそうな感じです。
:three:一番流行っているらしいのが「Apartment」というGemです。違うテナントは違うsubdomainを通じてデータの隔離することを実現します。
:four:Apartment+PostgreSQLの場合、微妙な問題がありそうです。未だに完璧に解決できていないようです。
:five:二番目有名なGemは「acts_as_tenant」というGemです。今回使ってみたのはこれです。

いよいよ始めよう

:one: インストールはとっても簡単

  1. gem 'acts_as_tenant'をGemfileに入れます

  2. Bundle Installを実行します。

  3. 完了です。

:two: データを隔離したいテーブルにテナントを代表するIDの列を追加

rails g migration addAccountToTablesでMigration Fileを生成させ、下記のように書きます。
image.png

説明:
① dealsは仕訳を保存するテーブル、bank_accounts は銀行口座を保存するテーブルです。そしてユーザごとにデータを隔離したいテーブルです。両方とも既にあったテーブルです。

② usersは既にあったユーザを保存するテーブルです。今回はuserごとにデータを隔離したいので、ここでは:user_idを入れてOKです。もし一つのAccount(Tenant)に複数のuserが含まれ、同じTenantのuserたちはデータを共有するという形がほしかったら、別途Accountテーブルを作る必要があります。

③ 勘定科目を共有したいため、勘定科目テーブルgl_accountsはそのまま変わらないです。

p.s.Migration Fileの名前は「AddAccountToTables」じゃなくても何でもいいです。

:three: Modelにacts_as_tenant(:user)を追加
image.png
image.png
隔離したいModelだけが必要です。勘定科目のmodel-GlAccountはそのまま何も変わらないです。

:four: テナントを判別するコードをcontrollerに入れる
image.png
説明:
① ここのset_current_tanant_through_filterはgemが提供してくれる関数です。名前は変えられないです。
find_current_tenantは自分で作ったprivate関数です。好きな名前にしてもOKです。
set_current_tenantはgemが提供してくれる関数です。名前は変えられないです。
④ パラメータのcurrent_userは自分がその前に書いた関数です。目的はログインしているユーザをゲットすることです。
:sunny:
以上だけ設定すると、ユーザAもBも自分しか見れない/作れないデータをできるようになりました。
非常にシンプルで分かりやすいGemだと思います。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1