Jumpstart docs logo Back to the app

Multitenancy

Overview

Jumpstart Pro supports multi-tenancy out-of-the-box by using the Account model to scope access to resources. This forbids users that are not associated to a given account from seeing the resources that belong to that account. The below diagram illustrates this functionality:

Diagram of how resources are scoped to accounts in Jumpstart Pro

With multi-tenancy in place resources can be transferred between accounts easily by updating the `account_id` attribute of a given resource from the old account_id to the new account_id. The diagram below shows transferring a project to another account using this approach:

Diagram of how to transfer resources to another accounts in Jumpstart Pro

Setting The Account/Tenant

The process of finding and setting the current_account can be configured in the configuration wizard, as shown in the screenshot below:

Screenshot of configuring how accounts are set via the config wizard in Jumpstart Pro

When a request is made to your application, Jumpstart Pro automatically uses these configurations to determine how to look up an account and properly scope the resources to the current_account.

Multitenancy with Associations

For instance, when creating a resource like the Project model, you can specify that a project belongs_to an account using the following command:

rails g model Project account:belongs_to title:string

Once set up, you can easily scope projects to the current_account in your ProjectsController:

class ProjectsController < ApplicationController
  def index
    @projects = current_account.projects
  end

  def new
    @project = current_account.projects.new
  end
end

Using the association scopes the Projects to the current_account. The downside is accessing Project.all would return Projects for any account.

To safeguard against this, you can integrate the act_as_tenant gem via the "Dependencies" section of the configuration wizard. This is especially useful for ensuring that queries are properly scoped to an account in the event you forget to do something like the above code example where the scoping is written by you in your controller actions or other queries. More information on acts_as_tenant is provided below.

Multitenancy with ActsAsTenant

To enable multitenancy with ActsAsTenant you can do so in the Dependencies section of the Jumpstart Pro configuration wizard UI located at /jumpstart.

Screenshot of Jumpstart Pro Dependencies configuration wizard

Supporting multitenancy with acts_as_tenant involves setting the current_account and scoping all model queries to that account.

Enabling multitenancy with acts_as_tenant is optional and must be specified for each model requiring tenant scoping. Any models without multitenancy will be globally available. It's recommended to keep models like User and Account globally available outside of tenants.

To scope a resource to a tenant, ensure your model has an account_id:integer column in the database, and then add acts_as_tenant :account to the model:

class Project < ApplicationRecord
  acts_as_tenant :account
end

This automatically adds a belongs_to :account association and scopes all queries on the model to the current_account. For example, calling Post.all produces the same results as current_account.posts.

If current_account is nil, all records will be returned. To change this behavior and raise an exception if current_account is nil, add the following initializer:

# config/initializers/acts_as_tenant.rb
ActsAsTenant.configure do |config|
  config.require_tenant = true
end

By enabling this feature, calling Project.all without a tenant set will result in an ActsAsTenant::NoTenant error.

To learn more about ActsAsTenant, check out the Row-level Multitenancy with ActsAsTenant video on GoRails.