I have a 4.2 multi-player rails app using Apartment gem, which was awesome.
Each company has its own subdomain. I use a custom “elevator” that looks at the full request host to determine which “tenant” should be loaded.
When I create a new company, I have an after_create hook to create a new tenant with the appropriate request host.
It seems that this always requires a server restart both in development and in production, otherwise I get a "Found not found" error.
It uses sqlite in development and postgres in production.
Do I need to restart the server every time I create a new tenant? Is there an automated way to do this? Maybe just restarting the initializer will work, but I'm not sure how to do it / if possible?
I have been working on this month and could not find a solution that works. Please, help!
Initializers / apartment.rb
require 'apartment/elevators/host_hash'
config.tenant_names = lambda { Company.pluck :request_host }
Rails.application.config.middleware.use 'Apartment::Elevators::HostHash', Company.full_hosts_hash
Initializers / host_hash.rb
require 'apartment/elevators/generic'
module Apartment
module Elevators
class HostHash < Generic
def initialize(app, hash = {}, processor = nil)
super app, processor
@hash = hash
end
def parse_tenant_name(request)
if request.host.split('.').first == "www"
nil
else
raise TenantNotFound,
"Cannot find tenant for host #{request.host}" unless @hash.has_key?(request.host)
@hash[request.host]
end
end
end
end
end
Company model
after_create :create_tenant
def self.full_hosts_hash
Company.all.inject(Hash.new) do |hash, company|
hash[company.request_host] = company.request_host
hash
end
end
private
def create_tenant
Apartment::Tenant.create(request_host)
end
What ended up working
I changed the configuration of the elevator to get away from HostHash, which was on the plane of the apartment, and used completely normal. Basically, based on the issue of gemub jewels of the apartment: https://github.com/influitive/apartment/issues/280
Initializers / apartment.rb
Rails.application.config.middleware.use 'BaseSite::BaseElevator'
application / intermediate / base_site.rb
require 'apartment/elevators/generic'
module BaseSite
class BaseElevator < Apartment::Elevators::Generic
def parse_tenant_name(request)
company = Company.find_by_request_host(request.host)
return company.request_host unless company.nil?
fail StandardError, "No website found at #{request.host} not found"
end
end
end