Rails Multi Tenancy
Aaron McLeod
What is multitenancy?
Multitenancy refers to multiple organizations utilizing one application, but they have their own unique data store.
Apartment Gem
Benefits
- Allows you to connect to the different databases when you want
- Able to use rack middleware (subdomain for a db for example)
- Allows you to create dbs very easily
Caveats
- New migration task on depoyments
- Connection needs to be reset to root after request is done
The Code
Apartment::Database.create(db_name) # creates the new database
Apartment::Database.switch(db_name) # connects to it
Apartment::Database.switch # connects to default db for current env
# tell apartment the db names
Apartment.configure do |config| config.database_names = lambda { Client.pluck("db_name") } end
def api_key_check
Apartment::Database.switch
client = Client.find_by_api_key(params[:key)
if client.nil?
raise ActionController::RoutingError.new 'Not Found'
else
Apartment::Database.switch client.db_name
end
end
What about encryption?
attr_encrypted
class Client < ActiveRecord::Base before_create :populate_fields after_create :create_client_db attr_encrypted :name, :encryption_key, key: Settings.encryption_key
# ...
end
class Project < ActiveRecord::Base
attr_encrypted :name, :description, key: proc { |project| encryption_key }
class << self
def encryption_key
@encryption_key
end
def encryption_key=(value)
if @encryption_key.nil?
@encryption_key = value
end
end
end
end
class Project < ActiveRecord::Base
attr_encrypted :name, :description, key: proc { |project| encryption_key }
class << self
def encryption_key
@encryption_key
end
def encryption_key=(value)
if @encryption_key.nil?
@encryption_key = value
end
end
end
end
class Api::V1::ProjectsController < ApplicationController before_filter :api_key_check def create Project.encryption_key = @client.encryption_key @project = Project.create project_params
end
end
Rails multi tenancy
By agmcleod
Rails multi tenancy
- 1,835