Multitenancy
Overview
Jumpstart Pro supports multi-tenancy out-of-the-box by using the Organization model to scope access to resources. This forbids users that are not associated to a given organization from seeing the resources that belong to that organization. The below diagram illustrates this functionality:
With multi-tenancy in place resources can be transferred between organizations easily by updating the `organization_id` attribute of a given resource from the old organization_id to the new organization_id. The diagram below shows transferring a project to another organization using this approach:
Setting The Organization/Tenant
The process of finding and setting the current_organization 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 organization and properly scope the resources to the current_organization.
Multitenancy with Associations
For instance, when creating a resource like the Project model, you can specify that a project belongs_to an organization using the following command:
rails g model Project organization:belongs_to title:string
Once set up, you can easily scope projects to the current_organization in your ProjectsController:
class ProjectsController < ApplicationController
def index
@projects = current_organization.projects
end
def new
@project = current_organization.projects.new
end
end
Using the association scopes the Projects to the current_organization. The downside is accessing Project.all would return Projects for any organization.
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 organization 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.
Supporting multitenancy with acts_as_tenant involves setting the current_organization and scoping all model queries to that organization.
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 Organization globally available outside of tenants.
To scope a resource to a tenant, ensure your model has an organization_id:integer column in the database, and then add acts_as_tenant :organization to the model:
class Project < ApplicationRecord
acts_as_tenant :organization
end
This automatically adds a belongs_to :organization association and scopes all queries on the model to the current_organization. For example, calling Post.all produces the same results as current_organization.posts.
If current_organization is nil, all records will be returned. To change this behavior and raise an exception if current_organization 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.