Written by Chris Oliver
multitenancy is a term used to describe a single software application that handles user (tenant) data separately.
The term “software multitenancy” refers to a software architecture in which a single instance of software runs on a server and serves multiple tenants. Systems designed in such manner are often called shared. A tenant is a group of users who share a common access with specific privileges to the software instance.
ActsAsTenant implements row-level multitenancy for Rails. It’s a popular, well loved gem that takes advantage of several features in Rails to make multitenancy easy to use.
Row-level multitenancy is when you add a
tenant_id column to all the models that should be scoped to a tenant. When you query or insert new records, a
tenant_id is always required to separate the data between tenants.
Another approach is using database schemas for multitenancy. Postgres databases have schemas with tables inside them. Each tenant gets its own schema with their own unique tables. This is great for separating out data but makes it complicated to run migrations and scale up as you have more tenants.
After you install ActsAsTenant, you’ll need to do two things:
You might already have a tenant model already like Account, Team, Organization, User, etc. You’ll simply need to add an association to each of your models that you want scoped by ActsAsTenant.
rails g scaffold Account name subdomain domain rails g scaffold Project account_id:integer name description:text
Once created, you can edit your models to use
class Project # This adds a belongs_to :account behind the scenes so you don't have to acts_as_tenant(:account) end
You might notice we added
domain fields to our Account tenant model. We can use these fields to automatically set the current tenant for a request based upon the subdomain or domain in the URL.
To set the current tenant automatically, we just need to add one line to our ApplicationController
class ApplicationController < ActionController::Base set_current_tenant_by_subdomain_or_domain(:account, :subdomain, :domain) end
This will set the current which you can access anywhere by calling
Once a tenant is set, calling
Project.all will return only the projects for the current tenant. It does this by adding a
default_scope to automatically filter queries to the current tenant. ActsAsTenant will also automatically set the tenant ID when you call
These changes make it easy to write code that creates and queries records in the current tenant. You don’t have to worry about forgetting to set a tenant ID on a record, it’s all done for you.