atrk.gif
    • Quick Contact: 1 212.714.6135

Multi-tenancy in Rails

What Multi-tenancy means? In simple definition it is a principle in software architecture where a single instance of the application serves multiple client organizations.

Here client organizations are considered as a tenant. In a multi-tenant architecture, application is designed virtually to partition its data and configuration so that each client organization works with a customized virtual application instance.

Multi-tenant application mainly has three type of users.

Admins: These are the clients who own the site and have top-level access.

Managers: These are the resources from the company. They manage the projects and users at the company level.

Users: These are the end users of this application. Here each page will be accessible to users depending on their authorizations.

Advantages of Multi-tenancy:

  1. Cost savings: Multi-tenancy allows for cost savings by considering resources and softwares used in the application. Cost and maintenance will increased when multiplied by many customers, especially if the customers are small. Multi-tenancy reduces this overhead by sharing same power resources and softwares. Software requires the licenses and support which will increases the cost if it needs to buy for every customer (single-tenancy). Shared infrastructure leads to lower costs.
  2. Scalability: A multi-tenant architecture makes it easy to increase capacity when more strength & power is required. When adding new hardware to the platform, the total capacity of the entire system increases and becomes more scalable, not for just a single client but for all the associated clients. Adding the features for a single client makes it available to other clients.
  3. Service: In multi-tenant application monitoring and administration will be required for one platform instead of managing different sets for each client. A multi-tenant SaaS provider can deliver more efficient and effective service and support, including troubleshooting and problem resolution.
  4. Upgrades: Upgrading the softwares version or system resources for multi-tenant applications (like dbs, servers, h/w resources etc.) are easy since there is a single, centralized place to go to make upgradation, installation etc.

Multi-tenancy in rails can be achieved with many architectures, some of them are listed below. Main feature in multi-tenancy should be there access privacy between all the resources(Admin, Manager and User.)

Using namespaces

# Admin controller

class Admin::ProjectsController < ApplicationController
  before_action :authenticate_admin_user! # for devise gem
  def show
    @project = Project.find(params[:id])
  end
end

 

# User controller

class ProjectsController < ApplicationController
  before_action :authenticate_user!
  def show
    # here projects are associated with a user as many associations.
    @project = current_user.projects.find(params[:id]) 
  end
end

 

# Management controller

class Management::ProjectsController < ApplicationController
  before_action :authenticate_company_user!
  before_action :find_company
  
  def show
   # here projects are associated with the company as many association 
   # or through:users and user belongs to the company.
   @project = company.projects.find(params[:id])
  end

private
  # can be moved to more appropriate place
  def find_company
    @company = company_user.company
  end
end

Using default_scope (Ryan Bates Multi-tenancy with Scopes)

Consider below schema:

class Company < ActiveRecord::Base
  attr_accessible :name
  cattr_accessor :current_id
end

class ApplicationController
  around_action :scope_current_company
  private
  def scope_current_company
    Company.current_id = current_tenant.id
    yield
    ensure
    Company.current_id = nil
  end
end

class User < ActiveRecord::Base
  default_scope { where (:company_id => Company.current_id) }
end

 

Above approach might not be feasible as it is extensively depends on class variable and if we not able to manage class variables as per thread.

Above can be achieved by using gem act_as_tenant https://github.com/ErwinM/acts_as_tenant

Separate Database (Apartments Method)

In gem apartment https://github.com/influitive/apartment, we can use separate databases for each company. This makes system more secure by considering data will not be sharable to other company.

Shared Database, Shared Schema (Using scopes and Model partitioning)

Sometimes we require that data of two companies can be shared within their users. We can achieve multi-tenancy by using scopes.

Consider below schema:

User |id|name|email|…|tenant_id|

Project |id|name|…|tenant_id|

The shared schema approach has the lowest hardware and backup costs, because it allows you to serve the largest number of tenants per database server. However, because multiple tenants share the same database tables, and this approach may require additional development effort in the area of security, to ensure that tenants can never access other tenant’s data, even in the event of unexpected bugs or attacks.

Advantage of the above approach is -

  • * No special deployment or infrastructure required.

Disadvantage would be -

  • * Relies on application query logic.
  • * Does not inherently prevent data leakage.
  • * Scaling with performance.

To achieve above, we can use gem multitenant https://github.com/wireframe/multitenant

When we are dealing with multi-tenant architecture we always need to consider the bug and exceptions. As this will not only affect one customer of tenant, it will affect functionalities of all the customers of the architecture.

LinkedInShare
This entry was posted in Ruby on Rails Training, Technology. Bookmark the permalink.

One Response to Multi-tenancy in Rails

  1. Smithc921 Smithc921 says:

    I am now not certain the place you’re getting your info, however good topic. I needs to spend some time learning more or figuring out more. Thank you for magnificent info I was on the lookout for this information for my mission.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>