# app/models/schema_manager.rb class SchemaManager class << self def create_schema(organization_id) schema_name = schema_name_for(organization_id) ActiveRecord::Base.connection.execute("CREATE SCHEMA IF NOT EXISTS #{schema_name}") with_schema(organization_id) do # Run all existing migrations in this schema migration_context = ActiveRecord::MigrationContext.new(Rails.application.paths["db/migrate"].first) migration_context.migrate end end def drop_schema(organization_id) schema_name = schema_name_for(organization_id) ActiveRecord::Base.connection.execute("DROP SCHEMA IF EXISTS #{schema_name} CASCADE") end def with_schema(organization_id) schema_name = schema_name_for(organization_id) original_schema = ActiveRecord::Base.connection.schema_search_path begin ActiveRecord::Base.connection.schema_search_path = schema_name yield ensure ActiveRecord::Base.connection.schema_search_path = original_schema end end def schema_name_for(organization_id) "org_#{organization_id.to_s.gsub('-', '_')}" end # Migrate all existing organization schemas def migrate_all_schemas migration_context = ActiveRecord::MigrationContext.new(Rails.application.paths["db/migrate"].first) Organization.find_each do |org| puts "Migrating schema for #{org.name}..." org.with_schema do migration_context.migrate end end end # List all organization schemas def list_schemas result = ActiveRecord::Base.connection.execute( "SELECT schema_name FROM information_schema.schemata WHERE schema_name LIKE 'org_%'" ) result.map { |row| row['schema_name'] } end # Check if schema exists def schema_exists?(organization_id) schema_name = schema_name_for(organization_id) result = ActiveRecord::Base.connection.execute( "SELECT EXISTS(SELECT 1 FROM information_schema.schemata WHERE schema_name = '#{schema_name}')" ) result.first['exists'] end end end