井原(@ihara2525)です。
サブドメインでデータを分けたい(例えばhttps://bitjourney.slack.comみたいな)場合、RailscastsにあるMultitenancy with Scopesみたいに実現するのもありですが、その中でも参照されている、apartmentというgemを使うと、一つのRailsアプリケーションから複数のDBを扱う実装が、簡単にできそうです。
まずGemfileにapartmentを追加してbundle。
Gemfile
source 'https://rubygems.org' do ... gem 'apartment', '1.0.0' ... end
apartmentの設定ファイルをつくります。
rails g apartment:install
config/initializers/apartment.rbがつくられるので、中を編集。サブドメインで分ける場合は以下な感じになると思います。
config/initializers/apartment.rb
require 'apartment/elevators/subdomain' Apartment.configure do |config| config.excluded_models = %w(Tenant) config.tenant_names = -> { Tenant.pluck(:name) } config.prepend_environment = !Rails.env.production? end Rails.application.config.middleware.use 'Apartment::Elevators::Subdomain'
一点、config.prepent_environment
はデフォルトではコメントアウトされていて、ドキュメントによると
By default, and only when not using PostgreSQL schemas, Apartment will prepend the environment to the tenant name to ensure there is no conflict between your environments. This is mainly for the benefit of your development and test environments. Uncomment the line below if you want to disable this behaviour in production.
とのことなので、デフォルトでRails.envをDB名の頭につけてくれそうに読めたのですが、つけてくれなかったのでコメントを外しています。 上記の設定だとproductionのときはfalseになるので、TenantのnameでDBがつくられそうです。
テナントを管理するモデルをつくります、今回はそのままTenantという名前で。nameでそれぞれを識別することにします。null: false等適宜つけておきましょう。
rails g model tenant name:string rake db:migrate
で、試しに一つテナントをつくってみます。通常db/seeds.rbとかseed-fuとかを使うんだと思います。
rails c [1] pry(main)> Tenant.create(name: 'bitjourney')
で、テナントを作成。
rake apartment:create
これでdevelopment_bitjourneyというDBがつくられます。 その後はマイグレーションを実行すると、これらのDB全てに反映されていきます。
rake db:migrate
これで、bitjourney.lvh.me:3000等、Tenantがある場合にはページが表示されますし、unknown.lvh.me:3000等Tenantがない場合はApartment::TenantNotFoundが発生します。いい感じですね。
というわけで、こういうのって、マルチテナントっていうんですね。何という名前で調べれば良いかわかっていませんでした。