Created
April 28, 2012 15:11
-
-
Save boriscy/2519729 to your computer and use it in GitHub Desktop.
General module for multitenant
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
# app/controllers/application_controller.rb | |
# author: Boris Barroso | |
# email: boriscyber@gmail.com | |
class ApplicationController < ActionController::Base | |
layout lambda{ |c| | |
if (c.request.xhr? or params[:xhr]) | |
false | |
elsif params[:print].present? | |
"print" | |
else | |
"application" | |
end | |
} | |
include Controllers::Authentication | |
helper_method Controllers::Authentication.helpers | |
#rescue_from Exception, :with => :render_error | |
include Controllers::Authorization | |
include Controllers::OrganisationHelpers | |
helper_method Controllers::OrganisationHelpers.organisation_helper_methods | |
protect_from_forgery | |
before_filter :set_user_session, :if => :user_signed_in? | |
before_filter :set_page | |
before_filter :set_organisation, :if => :organisation? | |
# Sets the organisation_id to help to set in the models and the search path | |
def set_organisation | |
raise "You must set the organisation" if session[:organisation].blank? | |
OrganisationSession.set session[:organisation] | |
begin | |
PgTools.set_search_path PgTools.get_schema_name(session[:organisation][:id]) | |
rescue | |
session[:organisation] = nil | |
session[:user_id] = nil | |
redirect_to "/users/sign_out" | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
# app/models/organisation_session.rb | |
# author: Boris Barroso | |
# email: boriscyber@gmail.com | |
# Used to access the organisation_id in the models | |
class OrganisationSession | |
KEYS = [:id, :name, :currency_id, :currency_name, :currency_symbol, :due_date] | |
class << self | |
attr_reader :organisation_id, :name, :currency_id | |
# Stores using de application_controller the current_user for devise | |
# @param [Hash] details from the organisation | |
def set(organisation) | |
raise "The OrganisationSession couln't be set' the param must be a hash" unless organisation.is_a? Hash | |
@organisation_id = organisation[:id] | |
@name = organisation[:name] | |
@currency_id = organisation[:currency_id] | |
end | |
alias set= set | |
# Initialize variables | |
def destroy | |
@organisation_id = @org_name = @currency_id = nil | |
end | |
# Returns the currencies of the current organisation | |
def currencies | |
o = Organisation.find(@organisation_id) | |
[o.currency]+ o.currencies | |
end | |
def currency_name | |
current_organisation.currency_name | |
end | |
def currency_plural | |
current_organisation.currency_plural | |
end | |
def currency_symbol | |
current_organisation.currency_symbol | |
end | |
def current_organisation | |
@org ||= Organisation.find(organisation_id) | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/pg_tools.rb | |
module PgTools | |
extend self | |
def get_schema_name(id) | |
"schema#{id}" | |
end | |
def public_schema? | |
res = connection.execute("SHOW search_path") | |
res.getvalue(0,0) === "public" | |
end | |
def with_schema(schema_name) | |
old_search_path = connection.schema_search_path | |
set_search_path(schema_name) | |
connection.schema_search_path = schema_name | |
result = yield | |
connection.schema_search_path = old_search_path | |
reset_search_path | |
result | |
end | |
def set_search_path(schema_name) | |
connection.execute "SET search_path TO #{schema_name}" | |
end | |
def reset_search_path | |
connection.execute "SET search_path TO public" | |
ActiveRecord::Base.connection.reset! | |
end | |
def current_search_path | |
connection.select_value "SHOW search_path" | |
end | |
def create_schema(schema_name) | |
raise "#{schema_name} already exists" if schema_exists?(schema_name) | |
ActiveRecord::Base.logger.info "Create #{schema_name}" | |
connection.execute "CREATE SCHEMA #{schema_name}" | |
end | |
def drop_schema(schema_name) | |
raise "#{schema_name} does not exists" unless schema_exists?(schema_name) | |
ActiveRecord::Base.logger.info "Drop schema #{schema_name}" | |
connection.execute "DROP SCHEMA #{schema_name} CASCADE" | |
end | |
def migrate_schema(schema_name, version = nil) | |
with_schema(schema_name) do | |
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, version ? version.to_i : nil) | |
end | |
end | |
def load_schema_into_schema(schema_name) | |
ActiveRecord::Base.logger.info "Enter schema #{schema_name}." | |
with_schema(schema_name) do | |
file = "#{Rails.root}/db/schema.rb" | |
if File.exists?(file) | |
ActiveRecord::Base.logger.info "Load the schema #{file}" | |
load(file) | |
else | |
raise "#{file} desn't exist yet. It's possible that you just ran a migration!" | |
end | |
end | |
end | |
def schema_exists?(schema_name) | |
all_schemas.include?(schema_name) | |
end | |
def all_schemas | |
connection.select_values("SELECT * FROM pg_namespace WHERE nspname != 'information_schema' AND nspname NOT LIKE 'pg%'") | |
end | |
def with_all_schemas | |
all_schemas.each do |schema_name| | |
with_schema(schema_name) do | |
yield | |
end | |
end | |
end | |
protected | |
def connection | |
ActiveRecord::Base.connection | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment