Multitenancy and uniqueness

Enectiva is a multitenant application which means we take care to separate data of different customers and avoid leaks between them. Luckily, there’re are many gems which help with common use cases and augment Ruby on Rails code to restrict queries by default.

We’ve been using the multitenant gem since the beginning and it does exactly what we expect it to do. More precisely it did, until we ran into uniqueness validation.

One of our new features requires a model with a field which needs to be unique within the scope of each tenant. Multitenant is installed, Rails have uniqueness validator built in so our initial code looked roughly like:

class TimeSeries < ActiveRecord::Base
    belongs_to :customer
    belongs_to_multitenant :customer
    validates :identifier, uniqueness: true

Only built-in methods are used, it’s readable, no regular expression involved; therefore, there’s no need to write a separate test. However, when we finished the feature and reviewed the code a doubt crept in. Does it actually does what we think it does? A quick look into the SQL log showed us the latter is correct!

A simple test verified that the uniqueness is ensured on the application level, which essentially means data leakage between customers. Our next thought was that there’s a bug in the multitenant gem, but a quick discussion revealed that only our assumptions are wrong.

There are cases when application-wide uniqueness makes sense even in a multitenant application. The obvious example is users' e-mails. Of course, tenant-wide uniqueness has many uses as well; however, they’re more circumstance specific. The question is how to achieve it?

Rails documentation revealed that it is possible to supply a list of fields as scope for uniqueness check. The code then changes to:

    validates :identifier, uniqueness: { scope: :customer_id }

In order to save others this trip and possibly prevent a bug, we updated multitenant’s documentation with an example. The PR has been already accepted.

The takeaway is: make sure you to verify your assumptions.

We're looking for developers to help us save energy

If you're interested in what we do and you would like to help us save energy, drop us a line at

comments powered by Disqus