Multitenant Ruby Gem

Ryan Sonnek bio photo By Ryan Sonnek

Multitenant: locking down your app and making cross tenant data leaks a thing of the past…since 2011

Designing multi-tenant applications has increasingly becoming the norm for software developers. The benefits of building an application with a multi-tenant architecture are almost too many to list (cost savings, data mining, simplified operations, etc). But, let there be no doubt that building a multi-tenant application increases the overall complexity of the application.

The Multitenant gem helps alleviate that complexity and ensures that all SQL queries executed adhere to the scoping of the current tenant. It works with any Rails3 compatible application without any modifications to your existing schema.

To configure, add the belongs_to_multitenant declaration to any model that has an association to a particular tenant.  This will inject a new SQL scope into your model.

class User  belongs_to :tenant

Now, all queries executed within the Multitenant.with_tenant block will automatically be scoped to the current tenant. No longer must you worry about a stray MyModel.all call exposing data to the wrong users! Also, any new records created within this block will automatically be associated to the current tenant. Another win for ensuring data separation!

# use an Rails around_filter to setup this block
Multitenant.with_tenant current_tenant do
  # queries within this block are automatically
  # scoped to the current tenant

  # records created within this block are
  # automatically assigned to the current tenant
  User.create :name => 'Bob'

Unintentionally leaking data between tenants should be the NUMBER ONE concern when building multi-tenant apps and it surprises me how few resources are available to assist developers in building multi-tenant apps and ensuring data separation between tenants. So, if you’re building a multi-tenant Rails app, make sure the Multitenant gem is in your toolbox!

Source code is 100% opensource and available on Github:

Gem is available on rubygems: