create org model and schema manager
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
class Current < ActiveSupport::CurrentAttributes
|
||||
attribute :session
|
||||
delegate :user, to: :session, allow_nil: true
|
||||
attribute :organization, :user
|
||||
end
|
||||
|
||||
27
app/models/organization.rb
Normal file
27
app/models/organization.rb
Normal file
@@ -0,0 +1,27 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Organization < ApplicationRecord
|
||||
validates :name, presence: true
|
||||
validates :subdomain, presence: true, uniqueness: true
|
||||
|
||||
after_create :create_schema
|
||||
before_destroy :drop_schema
|
||||
|
||||
def schema_name
|
||||
"org_#{id.to_s.gsub('-', '_')}"
|
||||
end
|
||||
|
||||
def with_schema(&block)
|
||||
SchemaManager.with_schema(id, &block)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_schema
|
||||
SchemaManager.create_schema(id)
|
||||
end
|
||||
|
||||
def drop_schema
|
||||
SchemaManager.drop_schema(id)
|
||||
end
|
||||
end
|
||||
67
app/models/schema_manager.rb
Normal file
67
app/models/schema_manager.rb
Normal file
@@ -0,0 +1,67 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user