Skip to content

Instantly share code, notes, and snippets.

@nathanscott
Last active May 30, 2016 19:33
Show Gist options
  • Save nathanscott/1ba9428ea51c0c568594e741c6772224 to your computer and use it in GitHub Desktop.
Save nathanscott/1ba9428ea51c0c568594e741c6772224 to your computer and use it in GitHub Desktop.
Multi-tenancy set up using Rails + Houser
# config/application.rb
require './app/middleware/company_middleware.rb'
module MyApp
class Application < Rails::Application
config.middleware.use 'Houser', class_name: 'Company'
config.middleware.use 'CompanyMiddleware'
end
end
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
expose(:current_company) { env['X-Houser-Object'] }
before_filter :within_company_context, if: :devise_controller?
before_filter :set_default_subdomain
def set_default_subdomain
SetUrlOptions.call current_company, default_url_options
end
def within_company_context
return if current_company.present?
render text: 'Not Found', status: 404
end
end
# app/middleware/company_middleware.rb
class CompanyMiddleware
def initialize(app)
@app = app
end
def call(env)
unless env['PATH_INFO'][%r{/assets/}]
current_company = find_company_by_domain env
env['X-Houser-Object'] = current_company unless current_company.nil?
end
app.call(env)
end
private
attr_reader :app
def find_company_by_domain(env)
return nil unless env['HTTP_HOST']
Company.find_by domain: env['HTTP_HOST']
end
end
# config/environments/development.rb
MyApp::Application.configure do
ENV['DEFAULT_HOST'] ||= 'myapp.dev'
end
# config/environments/production.rb
MyApp::Application.configure do
ENV['DEFAULT_HOST'] ||= 'myapp.com'
end
# app/lib/set_url_options.rb
class SetUrlOptions
def self.call(current_company, *option_hashes)
option_hashes += [
Rails.application.config.action_mailer.default_url_options,
ActionMailer::Base.default_url_options,
Rails.application.routes.default_url_options
]
option_hashes.each { |options| new(current_company, options).call }
end
def initialize(current_company, options)
@current_company, @options = current_company, options
end
def call
if current_company.nil?
options.delete :subdomain
options[:host] = ENV['DEFAULT_HOST']
elsif current_company.domain.blank?
options[:subdomain] = current_company.subdomain
options[:host] = ENV['DEFAULT_HOST']
else
options.delete :subdomain
options[:host] = current_company.domain
end
end
private
attr_reader :current_company, :options
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment