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:
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:
The process of finding and setting the current_account
can be configured in the configuration wizard, as shown in the screenshot below:
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
.
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.
To enable multitenancy with ActsAsTenant you can do so in the Dependencies section of the Jumpstart Pro configuration wizard UI located at /jumpstart.
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.