Files
fizzy/config/initializers/tenanting.rb
T
Mike Dalessio e68e2eb971 Patch Turbo to use the request script name
so that the URLs generated during view rendering are correct
2025-07-01 15:56:14 -04:00

59 lines
1.8 KiB
Ruby

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
ActiveSupport.on_load(:action_controller_base) do
before_action { logger.struct tenant: ApplicationRecord.current_tenant }
end
module TurboStreamsJobExtensions
extend ActiveSupport::Concern
class_methods do
def render_format(format, **rendering)
if ApplicationRecord.current_tenant
script_name = "/#{ApplicationRecord.current_tenant}"
ApplicationController.renderer.new(script_name: script_name).render(formats: [ format ], **rendering)
else
super
end
end
end
end
Rails.application.config.after_initialize do
Turbo::StreamsChannel.prepend TurboStreamsJobExtensions
end