Search code examples
ruby-on-railsmulti-tenantapartment-gem

disabling subdomains with Apartment


I'm using the apartment gem in a rails app.

I have one database with schemas for each tenant and one public schema for the Tenant table.

I have excluded the www subdomain:

Apartment::Elevators::Subdomain.excluded_subdomains = ['www']

Then, if I enter public.page.com or www.page.com, Apartment won't switch to another tenant, but it will stay at the public one. Of course "public" is not a tenant itself, is just the common data between tenants, so, I don't want any user using the public schema.

What would be the correct way to avoid this?

This app is running on AWS, so, route 53 is going to prevent this, but, although I want to avoid rails from serving request through this subdomain.


Solution

  • Apart from excluding domain from Apartment, you need to exclude them from routes. In my project I'm using this code for manage this:

    I'm using initializer to create array of excleded subdomains.

    # config/initializers/apartment/subdomain_exlusions.rb
    Apartment::Elevators::Subdomain.excluded_subdomains = ['www', 'admin']
    

    Then, we can use this array in helper class in routes.

    # config/routes.rb
    class ExcludedSubdomainConstraint
      def self.matches?(request)
        request.subdomain.present? && !Apartment::Elevators::Subdomain.excluded_subdomains.include?(request.subdomain)
      end
    end
    
    Rails.application.routes.draw do
      constraints ExcludedSubdomainConstraint do
        # here routes that are accessible in subdomains
      end
    end
    

    As a bonus, you can route excluded subdomains to another constrain

    
    class DashboardSubdomainConstraint
      def self.matches?(request)
        Apartment::Elevators::Subdomain.excluded_subdomains.include?(request.subdomain) || request.subdomain == ''
      end
    end
    
    constraints DashboardSubdomainConstraint do
      namespace :dashboard do
        get '/settings'
      end
    end
    

    will give you a route like www.domain.com/dashboard/settinigs with access to public tenant.

    TIP. And you can use different root method in concerns