← ClaudeAtlas

rails-multi-tenancylisted

Use when implementing URL-based multi-tenancy, CurrentAttributes, or account context patterns
mickzijdel/rails-toolkit · ★ 0 · AI & Automation · score 70
Install: claude install-skill mickzijdel/rails-toolkit
# Rails Multi-Tenancy Patterns ## Pattern 1: URL-Based Tenancy with Middleware Scope requests to tenants without subdomains or separate databases: Rack middleware extracts the tenant ID from the URL path, moves it from `PATH_INFO` to `SCRIPT_NAME` (making Rails think it's "mounted" at that prefix), and sets the tenant context for the request. ```ruby # config/initializers/tenanting/account_slug.rb module AccountSlug PATTERN = /(\d{7,})/ FORMAT = "%07d" PATH_INFO_MATCH = /\A(\/#{AccountSlug::PATTERN})/ class Extractor def initialize(app) @app = app end # Account id prefixes in the URL path. Rather than namespace all routes, # we "mount" the Rails app at this URL prefix. def call(env) request = ActionDispatch::Request.new(env) # $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 env["app.external_account_id"] = AccountSlug.decode($2) elsif request.path_info =~ PATH_INFO_MATCH # Yank the prefix off PATH_INFO and move it to SCRIPT_NAME request.engine_script_name = request.script_name = $1 request.path_info = $'.empty? ? "/" : $' env["app.external_account_id"] = AccountSlug.decode($2) end if env["app.external_account_id"] account = Account.find_by(external_account_id: env["app.external_account_id"]) Current.with_acc