module AccountSlug PATTERN = /(\d{7,})/ FORMAT = "%07d" PATH_INFO_MATCH = /\A(\/#{AccountSlug::PATTERN})/ # We're using account id prefixes in the URL path. Rather than namespace # all our routes, we're "mounting" the Rails app at this URL prefix. def self.extract(request) # $1, $2, $' == script_name, slug, path_info if request.script_name && request.script_name =~ PATH_INFO_MATCH # Likely due to restarting the action cable connection after upgrade AccountSlug.decode($2) elsif request.path_info =~ PATH_INFO_MATCH # Yanks the prefix off PATH_INFO and move it to SCRIPT_NAME request.engine_script_name = request.script_name = $1 request.path_info = $'.empty? ? "/" : $' # Limit session cookies to the slug path. # TODO TEST ME request.env["rack.session.options"][:path] = $1 # Return the account id for tenanting. AccountSlug.decode($2) end end def self.decode(slug) slug.to_i end def self.encode(id) FORMAT % id end end Rails.application.config.after_initialize do Rails.application.config.active_record_tenanted.tenant_resolver = ->(request) do AccountSlug.extract(request) end end