Search code examples
ruby-on-railsrubymulti-tenant

Converting a single Tenant Application to a multitenant one using Apartment gem


I've built a single tenant rails application with all core features ready to ship. But I now want to make it multi-tenant using the apartment gem. Most tutorials I've found all show how to start from scratch. But I find no pointers on how to convert an existing project to have multi-tenancy built in. From my research I found that all models need a tenant ID added in the migration. How do I add this to all existing models easily? Does installing the gem and running the generator suffice? I'm running a rails 5 API application with close to 30 models and using graphql ruby in an Ubuntu 18.04 environment.

Any ideas on how to do this?


Solution

  • Thanks @lacostenycoder for pointing me in the right direction. Here's what I did.

    Short answer: Yes, installing the gem, running the generator and creating your tenant model should suffice. Apartment reads your schema and creates schemas for the tenants.

    Long answer, my experience:

    1. I Backed up existing data from my database just in-case.
    2. Installed apartment gem
    3. If you are using any PostgreSQL database extensions like I was (pgcrypto, uuid- ssop)you need to understand that the extensions are not automatically loaded into the newly created schema.(look here for more details) do the following:

      • Follow instructions the github readme to create a shared_extensions schema
      • Create your first tenant. If it works, all is well. But...
      • If that doesn’t work, I mean when you create a tenant you get errors like ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR: function gen_random_uuid() does not exist
      • or ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR: function uuid_generate_v4() does not exist (more details here, here and here) like it was my case when creating my first tenant, I discovered that once the extensions are enabled on the public schema, they cannot be installed in the shared schema shared_extensions in this case. So you have to change them from the public schema to the shared_extensions schema. get more details here

      • If you are using uuid-ossp ALTER EXTENSION "uuid-ossp" SET SCHEMA shared_extensions in your rails dbconsole

      • If you are using pgcrypto ALTER EXTENSION "pgcrypto" SET SCHEMA shared_extensions in your rails dbconsole

    The apartment gem will create all models for your tenant once you have it set up correctly and create your first tenant.

    For more information on check out some of these github issues on apartment. Here and here. Took me a day to figure it out and gather that info. I hope it saves you time and headache!