namespace :tenant do desc "Migrate all tenant schemas" task migrate: :environment do # First migrate the public schema (organizations table, etc.) puts "Migrating public schema..." ActiveRecord::MigrationContext.new(Rails.application.paths["db/migrate"].first).migrate # Then migrate all tenant schemas puts "Migrating all tenant schemas..." SchemaManager.migrate_all_schemas puts "All schemas migrated successfully!" end desc "Migrate specific tenant schema" task :migrate_one, [:subdomain] => :environment do |task, args| subdomain = args[:subdomain] organization = Organization.find_by!(subdomain: subdomain) puts "Migrating schema for #{organization.name}..." organization.with_schema do ActiveRecord::MigrationContext.new(Rails.application.paths["db/migrate"].first).migrate end puts "Migration complete!" end desc "Rollback all tenant schemas" task :rollback, [:step] => :environment do |task, args| step = (args[:step] || 1).to_i Organization.find_each do |org| puts "Rolling back #{step} step(s) for #{org.name}..." org.with_schema do ActiveRecord::MigrationContext.new(Rails.application.paths["db/migrate"].first).rollback(step) end end end desc "Show migration status for all tenants" task status: :environment do Organization.find_each do |org| puts "\n#{org.name} (#{org.subdomain}):" org.with_schema do migration_context = ActiveRecord::MigrationContext.new(Rails.application.paths["db/migrate"].first) migration_context.migrations_status.each do |status, version, name| puts " #{status.center(8)} #{version} #{name}" end end end end desc "Create a new tenant" task :create, [:name, :subdomain] => :environment do |task, args| name = args[:name] subdomain = args[:subdomain] if name.blank? || subdomain.blank? puts "Usage: rails tenant:create[name,subdomain]" puts "Example: rails tenant:create['Acme Corp','acme']" exit 1 end organization = Organization.create!(name: name, subdomain: subdomain) puts "Created organization: #{organization.name}" puts "Schema: #{organization.schema_name}" puts "Access at: http://#{subdomain}.localhost:3000" end desc "Drop a tenant schema" task :drop, [:subdomain] => :environment do |task, args| subdomain = args[:subdomain] if subdomain.blank? puts "Usage: rails tenant:drop[subdomain]" exit 1 end organization = Organization.find_by!(subdomain: subdomain) print "Are you sure you want to drop #{organization.name}? (y/N): " response = STDIN.gets.chomp.downcase if response == 'y' || response == 'yes' organization.destroy puts "Dropped organization: #{organization.name}" else puts "Cancelled" end end end