Skip to content

Instantly share code, notes, and snippets.

@dhh
Created March 27, 2019 23:10
Show Gist options
  • Star 50 You must be signed in to star a gist
  • Fork 23 You must be signed in to fork a gist
  • Save dhh/23dea207f4e95d4b3ec5fac969c4a833 to your computer and use it in GitHub Desktop.
Save dhh/23dea207f4e95d4b3ec5fac969c4a833 to your computer and use it in GitHub Desktop.
module AccountSlug
PATTERN = /(\d{7,})/
FORMAT = '%07d'
def self.decode(slug) slug.to_i end
def self.encode(id) FORMAT % id end
# 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.
#
# The Extractor middleware yanks the prefix off PATH_INFO, moves it to
# SCRIPT_NAME, and drops the account id in env['bc3.account.queenbee_id'].
#
# Rails routes on PATH_INFO and builds URLs that respect SCRIPT_NAME,
# so the main app is none the wiser. We look up the current account using
# env['bc3.account.queenbee_id'] instead of request.subdomains.first
class Extractor
PATH_INFO_MATCH = /\A(\/#{AccountSlug::PATTERN})/
def initialize(app)
@app = app
end
def call(env)
request = ActionDispatch::Request.new(env)
# $1, $2, $' == script_name, slug, path_info
if request.path_info =~ PATH_INFO_MATCH
request.script_name = $1
request.path_info = $'.empty? ? '/' : $'
# Stash the account's Queenbee ID.
env['bc3.account.queenbee_id'] = AccountSlug.decode($2)
end
@app.call env
end
end
# Limit session cookies to the slug path.
class LimitSessionToAccountSlugPath
def initialize(app)
@app = app
end
def call(env)
env['rack.session.options'][:path] = env['SCRIPT_NAME'] if env['bc3.account.queenbee_id']
@app.call env
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment