pg_multitenant_schemas 0.1.3 โ 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.actrc +17 -0
- data/.env.local.example +21 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +86 -0
- data/LOCAL_TESTING_SUMMARY.md +141 -0
- data/README.md +269 -16
- data/TESTING_LOCALLY.md +208 -0
- data/docs/README.md +81 -0
- data/docs/configuration.md +340 -0
- data/docs/context.md +292 -0
- data/docs/errors.md +498 -0
- data/docs/github_actions_permissions_fix.md +136 -0
- data/docs/github_actions_setup.md +181 -0
- data/docs/integration_testing.md +454 -0
- data/docs/local_workflow_testing.md +314 -0
- data/docs/migrator.md +291 -0
- data/docs/rails_integration.md +468 -0
- data/docs/schema_switcher.md +182 -0
- data/docs/tenant_resolver.md +394 -0
- data/docs/testing.md +358 -0
- data/examples/context_management.rb +198 -0
- data/examples/migration_workflow.rb +50 -0
- data/examples/rails_integration/controller_examples.rb +368 -0
- data/examples/schema_operations.rb +124 -0
- data/lib/pg_multitenant_schemas/configuration.rb +4 -4
- data/lib/pg_multitenant_schemas/migration_display_reporter.rb +30 -0
- data/lib/pg_multitenant_schemas/migration_executor.rb +81 -0
- data/lib/pg_multitenant_schemas/migration_schema_operations.rb +54 -0
- data/lib/pg_multitenant_schemas/migration_status_reporter.rb +65 -0
- data/lib/pg_multitenant_schemas/migrator.rb +89 -0
- data/lib/pg_multitenant_schemas/schema_switcher.rb +40 -66
- data/lib/pg_multitenant_schemas/tasks/advanced_tasks.rake +21 -0
- data/lib/pg_multitenant_schemas/tasks/basic_tasks.rake +20 -0
- data/lib/pg_multitenant_schemas/tasks/pg_multitenant_schemas.rake +53 -143
- data/lib/pg_multitenant_schemas/tasks/tenant_tasks.rake +65 -0
- data/lib/pg_multitenant_schemas/tenant_task_helpers.rb +102 -0
- data/lib/pg_multitenant_schemas/version.rb +1 -1
- data/lib/pg_multitenant_schemas.rb +10 -5
- data/pg_multitenant_schemas.gemspec +10 -9
- data/pre-push-check.sh +95 -0
- data/rails_integration/app/controllers/application_controller.rb +6 -0
- data/rails_integration/app/models/tenant.rb +6 -0
- data/test-github-setup.sh +85 -0
- data/validate-github-commands.sh +47 -0
- metadata +49 -17
data/TESTING_LOCALLY.md
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# ๐ Quick Start: Testing GitHub Workflows Locally
|
|
2
|
+
|
|
3
|
+
This guide gets you up and running quickly with local GitHub Actions testing.
|
|
4
|
+
|
|
5
|
+
## ๐ฏ TL;DR - Quick Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# 1. Run pre-push checks (recommended before every push)
|
|
9
|
+
./pre-push-check.sh
|
|
10
|
+
|
|
11
|
+
# 2. Test GitHub Actions locally with act
|
|
12
|
+
act -l # List all workflows
|
|
13
|
+
act push # Test CI workflow
|
|
14
|
+
act pull_request # Test PR workflow
|
|
15
|
+
|
|
16
|
+
# 3. Manual component testing
|
|
17
|
+
bundle exec rubocop # Code style check
|
|
18
|
+
bundle exec rspec # Run tests
|
|
19
|
+
gem build *.gemspec # Test gem building
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## ๐ง One-Time Setup
|
|
23
|
+
|
|
24
|
+
### 1. Install act (if not already installed)
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# macOS
|
|
28
|
+
brew install act
|
|
29
|
+
|
|
30
|
+
# Linux
|
|
31
|
+
curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
|
|
32
|
+
|
|
33
|
+
# Windows
|
|
34
|
+
choco install act-cli
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 2. Create local environment file
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Copy the example and fill in your values
|
|
41
|
+
cp .env.local.example .env.local
|
|
42
|
+
|
|
43
|
+
# Edit with your actual tokens (optional, only needed for release testing)
|
|
44
|
+
nano .env.local
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## ๐งช Testing Strategies
|
|
48
|
+
|
|
49
|
+
### Strategy 1: Pre-Push Script (Recommended)
|
|
50
|
+
|
|
51
|
+
Run this before every push:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
./pre-push-check.sh
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
This runs:
|
|
58
|
+
- โ
RuboCop (code style)
|
|
59
|
+
- โ
RSpec (unit tests)
|
|
60
|
+
- โ
Security audit
|
|
61
|
+
- โ
Gem build test
|
|
62
|
+
- โ
Integration tests (if PostgreSQL available)
|
|
63
|
+
|
|
64
|
+
### Strategy 2: act - GitHub Actions Locally
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Test the main CI workflow
|
|
68
|
+
act push
|
|
69
|
+
|
|
70
|
+
# Test pull request workflow
|
|
71
|
+
act pull_request
|
|
72
|
+
|
|
73
|
+
# Dry run (see what would execute)
|
|
74
|
+
act -n
|
|
75
|
+
|
|
76
|
+
# Test specific job
|
|
77
|
+
act -j test
|
|
78
|
+
|
|
79
|
+
# List all available workflows and jobs
|
|
80
|
+
act -l
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Strategy 3: Manual Component Testing
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Test each component individually
|
|
87
|
+
bundle install
|
|
88
|
+
bundle exec rubocop
|
|
89
|
+
bundle exec rspec
|
|
90
|
+
bundle exec rspec --exclude-pattern '**/integration/**/*_spec.rb' # Unit tests only
|
|
91
|
+
bundle exec rspec --tag integration # Integration tests only
|
|
92
|
+
bundle audit
|
|
93
|
+
gem build pg_multitenant_schemas.gemspec
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## ๐ฏ Workflow-Specific Testing
|
|
97
|
+
|
|
98
|
+
### Testing CI Workflow (.github/workflows/main.yml)
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# With act
|
|
102
|
+
act push
|
|
103
|
+
|
|
104
|
+
# Manual simulation
|
|
105
|
+
bundle install
|
|
106
|
+
bundle exec rubocop
|
|
107
|
+
bundle exec rspec --exclude-pattern '**/integration/**/*_spec.rb'
|
|
108
|
+
bundle audit
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Testing Release Workflow (.github/workflows/release.yml)
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# With act (simulates main branch push)
|
|
115
|
+
act push --env GITHUB_REF=refs/heads/main
|
|
116
|
+
|
|
117
|
+
# Manual simulation (WITHOUT publishing)
|
|
118
|
+
# 1. Update version in lib/pg_multitenant_schemas/version.rb
|
|
119
|
+
# 2. Build gem locally
|
|
120
|
+
gem build pg_multitenant_schemas.gemspec
|
|
121
|
+
# 3. Check gem contents
|
|
122
|
+
gem contents pg_multitenant_schemas-*.gem
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## ๐ Troubleshooting
|
|
126
|
+
|
|
127
|
+
### act Issues
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Docker not running
|
|
131
|
+
# โ Start Docker Desktop
|
|
132
|
+
|
|
133
|
+
# Permission denied
|
|
134
|
+
# โ Fix Docker permissions or use sudo
|
|
135
|
+
|
|
136
|
+
# Platform issues
|
|
137
|
+
act --container-architecture linux/amd64
|
|
138
|
+
|
|
139
|
+
# Secrets not found
|
|
140
|
+
# โ Check .env.local file exists and has correct values
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### PostgreSQL Issues
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Check if PostgreSQL is running
|
|
147
|
+
pg_isready
|
|
148
|
+
|
|
149
|
+
# Start PostgreSQL (macOS)
|
|
150
|
+
brew services start postgresql@15
|
|
151
|
+
|
|
152
|
+
# Create test database
|
|
153
|
+
createdb pg_multitenant_test
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Ruby/Bundle Issues
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Install correct Ruby version
|
|
160
|
+
rbenv install 3.3.0
|
|
161
|
+
rbenv local 3.3.0
|
|
162
|
+
|
|
163
|
+
# Clean and reinstall gems
|
|
164
|
+
bundle clean --force
|
|
165
|
+
bundle install
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## ๐ Typical Workflow
|
|
169
|
+
|
|
170
|
+
1. **Make changes** to your code
|
|
171
|
+
2. **Run pre-push checks**: `./pre-push-check.sh`
|
|
172
|
+
3. **Fix any issues** found
|
|
173
|
+
4. **Test with act** (optional): `act push`
|
|
174
|
+
5. **Commit and push** when everything passes
|
|
175
|
+
|
|
176
|
+
## ๐ Integration with Git
|
|
177
|
+
|
|
178
|
+
Add to `.git/hooks/pre-push` to run checks automatically:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
#!/bin/bash
|
|
182
|
+
./pre-push-check.sh
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Make it executable:
|
|
186
|
+
```bash
|
|
187
|
+
chmod +x .git/hooks/pre-push
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## ๐ Success Indicators
|
|
191
|
+
|
|
192
|
+
You're ready to push when you see:
|
|
193
|
+
|
|
194
|
+
- โ
Pre-push script passes all checks
|
|
195
|
+
- โ
`act push` completes without errors
|
|
196
|
+
- โ
All tests pass locally
|
|
197
|
+
- โ
RuboCop shows no violations
|
|
198
|
+
- โ
Gem builds successfully
|
|
199
|
+
|
|
200
|
+
## ๐ More Information
|
|
201
|
+
|
|
202
|
+
- [Complete Guide](docs/local_workflow_testing.md) - Detailed documentation
|
|
203
|
+
- [GitHub Actions Docs](https://docs.github.com/en/actions)
|
|
204
|
+
- [act Documentation](https://github.com/nektos/act)
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
**๐ก Pro Tip**: Run `./pre-push-check.sh` before every commit to catch issues early!
|
data/docs/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# PG Multitenant Schemas - Core Architecture Documentation
|
|
2
|
+
|
|
3
|
+
This directory contains detailed documentation for each core component of the PG Multitenant Schemas gem.
|
|
4
|
+
|
|
5
|
+
## ๐ Core Components Overview
|
|
6
|
+
|
|
7
|
+
| Component | Purpose | Documentation |
|
|
8
|
+
|-----------|---------|---------------|
|
|
9
|
+
| **SchemaSwitcher** | Low-level PostgreSQL schema operations | [schema_switcher.md](schema_switcher.md) |
|
|
10
|
+
| **Context** | Thread-safe tenant context management | [context.md](context.md) |
|
|
11
|
+
| **Migrator** | Automated migration management system | [migrator.md](migrator.md) |
|
|
12
|
+
| **Configuration** | Gem configuration and settings | [configuration.md](configuration.md) |
|
|
13
|
+
| **TenantResolver** | Tenant identification and resolution | [tenant_resolver.md](tenant_resolver.md) |
|
|
14
|
+
| **Rails Integration** | Rails framework integration components | [rails_integration.md](rails_integration.md) |
|
|
15
|
+
| **Errors** | Custom exception classes | [errors.md](errors.md) |
|
|
16
|
+
| **Testing** | RSpec test suite and testing guide | [testing.md](testing.md) |
|
|
17
|
+
| **Integration Testing** | PostgreSQL integration testing guide | [integration_testing.md](integration_testing.md) |
|
|
18
|
+
| **CI/CD & Releases** | GitHub Actions automation setup | [github_actions_setup.md](github_actions_setup.md) |
|
|
19
|
+
| **Local Workflow Testing** | Test GitHub Actions locally before push | [local_workflow_testing.md](local_workflow_testing.md) |
|
|
20
|
+
|
|
21
|
+
## ๐๏ธ Architecture Flow
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
HTTP Request
|
|
25
|
+
โ
|
|
26
|
+
TenantResolver (identifies tenant)
|
|
27
|
+
โ
|
|
28
|
+
Context (sets tenant context)
|
|
29
|
+
โ
|
|
30
|
+
SchemaSwitcher (switches PostgreSQL schema)
|
|
31
|
+
โ
|
|
32
|
+
Rails Application (executes in tenant schema)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## ๐ง Key Concepts
|
|
36
|
+
|
|
37
|
+
### Schema-Based Multitenancy
|
|
38
|
+
- Each tenant gets their own PostgreSQL schema
|
|
39
|
+
- Complete data isolation between tenants
|
|
40
|
+
- Shared application code, separate data
|
|
41
|
+
|
|
42
|
+
### Thread-Safe Context
|
|
43
|
+
- Tenant context is stored per thread
|
|
44
|
+
- Safe for concurrent requests
|
|
45
|
+
- Automatic context restoration
|
|
46
|
+
|
|
47
|
+
### Automated Migrations
|
|
48
|
+
- Single command migrates all tenant schemas
|
|
49
|
+
- Error handling per tenant
|
|
50
|
+
- Progress tracking and status reporting
|
|
51
|
+
|
|
52
|
+
## ๐ Getting Started
|
|
53
|
+
|
|
54
|
+
1. **Read the [Configuration Guide](configuration.md)** to understand setup options
|
|
55
|
+
2. **Explore [Schema Switcher](schema_switcher.md)** for core PostgreSQL operations
|
|
56
|
+
3. **Learn [Context Management](context.md)** for tenant switching
|
|
57
|
+
4. **Master [Migration System](migrator.md)** for database management
|
|
58
|
+
5. **Understand [Rails Integration](rails_integration.md)** for framework features
|
|
59
|
+
6. **Review [Testing Guide](testing.md)** for development and testing practices
|
|
60
|
+
|
|
61
|
+
## ๐งช Testing and Development
|
|
62
|
+
|
|
63
|
+
- **[Testing Guide](testing.md)**: Comprehensive RSpec test suite documentation
|
|
64
|
+
- **[Integration Testing](integration_testing.md)**: PostgreSQL integration testing guide
|
|
65
|
+
- **[Local Workflow Testing](local_workflow_testing.md)**: Test GitHub Actions locally before push
|
|
66
|
+
- **Test Execution**: `bundle exec rspec` (unit tests) and `bundle exec rspec --tag integration` (integration tests)
|
|
67
|
+
- **Pre-Push Testing**: `./pre-push-check.sh` (validates CI components locally)
|
|
68
|
+
|
|
69
|
+
## ๐ Debug and Troubleshooting
|
|
70
|
+
|
|
71
|
+
- Check [Errors Documentation](errors.md) for exception handling
|
|
72
|
+
- Review [TenantResolver](tenant_resolver.md) for tenant identification issues
|
|
73
|
+
- Examine Context state for switching problems
|
|
74
|
+
- Use [Testing Guide](testing.md) for debugging test failures
|
|
75
|
+
|
|
76
|
+
## ๐ Additional Resources
|
|
77
|
+
|
|
78
|
+
- [Main README](../README.md) - Getting started guide
|
|
79
|
+
- [CHANGELOG](../CHANGELOG.md) - Version history
|
|
80
|
+
- [Examples](../examples/) - Usage examples
|
|
81
|
+
- [Specs](../spec/) - Test suite
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# Configuration - Gem Settings and Options
|
|
2
|
+
|
|
3
|
+
**File**: `lib/pg_multitenant_schemas/configuration.rb`
|
|
4
|
+
|
|
5
|
+
## ๐ Overview
|
|
6
|
+
|
|
7
|
+
The `Configuration` class manages all configurable aspects of the PG Multitenant Schemas gem. It provides a centralized way to customize behavior, set defaults, and integrate with different Rails applications.
|
|
8
|
+
|
|
9
|
+
## ๐ฏ Purpose
|
|
10
|
+
|
|
11
|
+
- **Centralized Settings**: Single location for all gem configuration
|
|
12
|
+
- **Framework Integration**: Seamless Rails integration options
|
|
13
|
+
- **Customization**: Flexible options for different deployment scenarios
|
|
14
|
+
- **Defaults Management**: Sensible defaults with override capabilities
|
|
15
|
+
|
|
16
|
+
## ๐ง Configuration Options
|
|
17
|
+
|
|
18
|
+
### Core Settings
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
PgMultitenantSchemas.configure do |config|
|
|
22
|
+
# Default schema to use (usually 'public')
|
|
23
|
+
config.default_schema = 'public'
|
|
24
|
+
|
|
25
|
+
# ActiveRecord connection class
|
|
26
|
+
config.connection_class = 'ApplicationRecord'
|
|
27
|
+
|
|
28
|
+
# Tenant model class name
|
|
29
|
+
config.tenant_model = 'Tenant'
|
|
30
|
+
|
|
31
|
+
# Schema naming strategy
|
|
32
|
+
config.schema_prefix = nil # No prefix by default
|
|
33
|
+
end
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Connection Management
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
PgMultitenantSchemas.configure do |config|
|
|
40
|
+
# Connection class for database operations
|
|
41
|
+
config.connection_class = 'ApplicationRecord' # Default
|
|
42
|
+
# config.connection_class = 'TenantRecord' # Custom connection
|
|
43
|
+
# config.connection_class = 'ReadOnlyRecord' # Read-only operations
|
|
44
|
+
end
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Tenant Resolution
|
|
48
|
+
|
|
49
|
+
```ruby
|
|
50
|
+
PgMultitenantSchemas.configure do |config|
|
|
51
|
+
# Model used for tenant lookup
|
|
52
|
+
config.tenant_model = 'Tenant' # Default
|
|
53
|
+
# config.tenant_model = 'Organization'
|
|
54
|
+
# config.tenant_model = 'Account'
|
|
55
|
+
|
|
56
|
+
# Attribute used for schema naming
|
|
57
|
+
config.tenant_schema_attribute = :subdomain # Default
|
|
58
|
+
# config.tenant_schema_attribute = :slug
|
|
59
|
+
# config.tenant_schema_attribute = :code
|
|
60
|
+
end
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Schema Management
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
PgMultitenantSchemas.configure do |config|
|
|
67
|
+
# Default schema for non-tenant operations
|
|
68
|
+
config.default_schema = 'public'
|
|
69
|
+
|
|
70
|
+
# Schema naming prefix (optional)
|
|
71
|
+
config.schema_prefix = 'tenant_' # Results in 'tenant_acme', 'tenant_beta'
|
|
72
|
+
# config.schema_prefix = nil # Results in 'acme', 'beta'
|
|
73
|
+
|
|
74
|
+
# Schema exclusion patterns
|
|
75
|
+
config.excluded_schemas = ['information_schema', 'pg_catalog', 'pg_toast']
|
|
76
|
+
end
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## ๐๏ธ Implementation Details
|
|
80
|
+
|
|
81
|
+
### Configuration Class Structure
|
|
82
|
+
|
|
83
|
+
```ruby
|
|
84
|
+
module PgMultitenantSchemas
|
|
85
|
+
class Configuration
|
|
86
|
+
attr_accessor :default_schema,
|
|
87
|
+
:connection_class,
|
|
88
|
+
:tenant_model,
|
|
89
|
+
:tenant_schema_attribute,
|
|
90
|
+
:schema_prefix,
|
|
91
|
+
:excluded_schemas
|
|
92
|
+
|
|
93
|
+
def initialize
|
|
94
|
+
@default_schema = 'public'
|
|
95
|
+
@connection_class = 'ApplicationRecord'
|
|
96
|
+
@tenant_model = 'Tenant'
|
|
97
|
+
@tenant_schema_attribute = :subdomain
|
|
98
|
+
@schema_prefix = nil
|
|
99
|
+
@excluded_schemas = default_excluded_schemas
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Dynamic Configuration Loading
|
|
106
|
+
|
|
107
|
+
The configuration supports dynamic loading and environment-specific settings:
|
|
108
|
+
|
|
109
|
+
```ruby
|
|
110
|
+
# Load from environment variables
|
|
111
|
+
config.default_schema = ENV['PG_MULTITENANT_DEFAULT_SCHEMA'] || 'public'
|
|
112
|
+
|
|
113
|
+
# Environment-specific configuration
|
|
114
|
+
if Rails.env.development?
|
|
115
|
+
config.schema_prefix = 'dev_'
|
|
116
|
+
elsif Rails.env.test?
|
|
117
|
+
config.schema_prefix = 'test_'
|
|
118
|
+
end
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## ๐ Usage Patterns
|
|
122
|
+
|
|
123
|
+
### Basic Configuration
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
# config/initializers/pg_multitenant_schemas.rb
|
|
127
|
+
PgMultitenantSchemas.configure do |config|
|
|
128
|
+
config.default_schema = 'public'
|
|
129
|
+
config.tenant_model = 'Organization'
|
|
130
|
+
config.connection_class = 'ApplicationRecord'
|
|
131
|
+
end
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Advanced Configuration
|
|
135
|
+
|
|
136
|
+
```ruby
|
|
137
|
+
# config/initializers/pg_multitenant_schemas.rb
|
|
138
|
+
PgMultitenantSchemas.configure do |config|
|
|
139
|
+
# Core settings
|
|
140
|
+
config.default_schema = 'shared'
|
|
141
|
+
config.tenant_model = 'Account'
|
|
142
|
+
config.tenant_schema_attribute = :slug
|
|
143
|
+
|
|
144
|
+
# Schema naming
|
|
145
|
+
config.schema_prefix = Rails.env.production? ? nil : "#{Rails.env}_"
|
|
146
|
+
|
|
147
|
+
# Connection management
|
|
148
|
+
config.connection_class = 'TenantRecord'
|
|
149
|
+
|
|
150
|
+
# Exclusions
|
|
151
|
+
config.excluded_schemas += ['analytics', 'logs']
|
|
152
|
+
end
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Environment-Specific Configuration
|
|
156
|
+
|
|
157
|
+
```ruby
|
|
158
|
+
# config/initializers/pg_multitenant_schemas.rb
|
|
159
|
+
PgMultitenantSchemas.configure do |config|
|
|
160
|
+
case Rails.env
|
|
161
|
+
when 'development'
|
|
162
|
+
config.schema_prefix = 'dev_'
|
|
163
|
+
config.default_schema = 'dev_public'
|
|
164
|
+
when 'test'
|
|
165
|
+
config.schema_prefix = 'test_'
|
|
166
|
+
config.default_schema = 'test_public'
|
|
167
|
+
when 'staging'
|
|
168
|
+
config.schema_prefix = 'staging_'
|
|
169
|
+
config.default_schema = 'public'
|
|
170
|
+
when 'production'
|
|
171
|
+
config.schema_prefix = nil
|
|
172
|
+
config.default_schema = 'public'
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## ๐๏ธ Configuration Validation
|
|
178
|
+
|
|
179
|
+
The gem includes configuration validation to catch common issues:
|
|
180
|
+
|
|
181
|
+
```ruby
|
|
182
|
+
def validate_configuration!
|
|
183
|
+
raise ConfigurationError, "tenant_model must be defined" if tenant_model.blank?
|
|
184
|
+
raise ConfigurationError, "default_schema cannot be blank" if default_schema.blank?
|
|
185
|
+
|
|
186
|
+
# Validate tenant model exists
|
|
187
|
+
begin
|
|
188
|
+
tenant_model.constantize
|
|
189
|
+
rescue NameError
|
|
190
|
+
raise ConfigurationError, "Tenant model '#{tenant_model}' not found"
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Validate connection class
|
|
194
|
+
begin
|
|
195
|
+
connection_class.constantize
|
|
196
|
+
rescue NameError
|
|
197
|
+
raise ConfigurationError, "Connection class '#{connection_class}' not found"
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## ๐ง Integration Examples
|
|
203
|
+
|
|
204
|
+
### Custom Tenant Models
|
|
205
|
+
|
|
206
|
+
```ruby
|
|
207
|
+
# For custom tenant model structure
|
|
208
|
+
class Organization < ApplicationRecord
|
|
209
|
+
has_many :users
|
|
210
|
+
|
|
211
|
+
def schema_name
|
|
212
|
+
"org_#{slug}"
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Configuration
|
|
217
|
+
PgMultitenantSchemas.configure do |config|
|
|
218
|
+
config.tenant_model = 'Organization'
|
|
219
|
+
config.tenant_schema_attribute = :schema_name
|
|
220
|
+
end
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Multiple Database Setup
|
|
224
|
+
|
|
225
|
+
```ruby
|
|
226
|
+
# For applications with multiple databases
|
|
227
|
+
class TenantRecord < ApplicationRecord
|
|
228
|
+
connects_to database: { writing: :tenant_primary, reading: :tenant_replica }
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
PgMultitenantSchemas.configure do |config|
|
|
232
|
+
config.connection_class = 'TenantRecord'
|
|
233
|
+
end
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Custom Schema Naming
|
|
237
|
+
|
|
238
|
+
```ruby
|
|
239
|
+
# Custom schema naming logic
|
|
240
|
+
module SchemaNameBuilder
|
|
241
|
+
def self.build_name(tenant)
|
|
242
|
+
case tenant.tier
|
|
243
|
+
when 'enterprise'
|
|
244
|
+
"ent_#{tenant.slug}"
|
|
245
|
+
when 'premium'
|
|
246
|
+
"prem_#{tenant.slug}"
|
|
247
|
+
else
|
|
248
|
+
"std_#{tenant.slug}"
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
PgMultitenantSchemas.configure do |config|
|
|
254
|
+
config.schema_name_builder = SchemaNameBuilder
|
|
255
|
+
end
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## ๐จ Important Considerations
|
|
259
|
+
|
|
260
|
+
### Configuration Timing
|
|
261
|
+
|
|
262
|
+
- Configure the gem **before** Rails application initialization
|
|
263
|
+
- Place configuration in `config/initializers/`
|
|
264
|
+
- Ensure configuration runs before model loading
|
|
265
|
+
|
|
266
|
+
### Thread Safety
|
|
267
|
+
|
|
268
|
+
- Configuration is **read-only** after initialization
|
|
269
|
+
- Safe to access from multiple threads
|
|
270
|
+
- No runtime configuration changes supported
|
|
271
|
+
|
|
272
|
+
### Performance Impact
|
|
273
|
+
|
|
274
|
+
- Configuration lookups are fast (cached)
|
|
275
|
+
- No database queries for configuration access
|
|
276
|
+
- Minimal memory overhead
|
|
277
|
+
|
|
278
|
+
## ๐ Configuration Debugging
|
|
279
|
+
|
|
280
|
+
### Check Current Configuration
|
|
281
|
+
|
|
282
|
+
```ruby
|
|
283
|
+
# Display current configuration
|
|
284
|
+
config = PgMultitenantSchemas.configuration
|
|
285
|
+
puts "Default Schema: #{config.default_schema}"
|
|
286
|
+
puts "Tenant Model: #{config.tenant_model}"
|
|
287
|
+
puts "Connection Class: #{config.connection_class}"
|
|
288
|
+
puts "Schema Prefix: #{config.schema_prefix}"
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Validate Configuration
|
|
292
|
+
|
|
293
|
+
```ruby
|
|
294
|
+
# Validate configuration is correct
|
|
295
|
+
begin
|
|
296
|
+
PgMultitenantSchemas.configuration.validate_configuration!
|
|
297
|
+
puts "โ
Configuration is valid"
|
|
298
|
+
rescue PgMultitenantSchemas::ConfigurationError => e
|
|
299
|
+
puts "โ Configuration error: #{e.message}"
|
|
300
|
+
end
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## ๐ Related Components
|
|
304
|
+
|
|
305
|
+
- **[Context](context.md)**: Uses configuration for default schema
|
|
306
|
+
- **[SchemaSwitcher](schema_switcher.md)**: Uses connection class configuration
|
|
307
|
+
- **[TenantResolver](tenant_resolver.md)**: Uses tenant model configuration
|
|
308
|
+
- **[Rails Integration](rails_integration.md)**: Framework-specific configuration
|
|
309
|
+
|
|
310
|
+
## ๐ Configuration Templates
|
|
311
|
+
|
|
312
|
+
### Standard Rails App
|
|
313
|
+
```ruby
|
|
314
|
+
PgMultitenantSchemas.configure do |config|
|
|
315
|
+
config.default_schema = 'public'
|
|
316
|
+
config.tenant_model = 'Tenant'
|
|
317
|
+
config.connection_class = 'ApplicationRecord'
|
|
318
|
+
end
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### SaaS Application
|
|
322
|
+
```ruby
|
|
323
|
+
PgMultitenantSchemas.configure do |config|
|
|
324
|
+
config.default_schema = 'shared'
|
|
325
|
+
config.tenant_model = 'Account'
|
|
326
|
+
config.tenant_schema_attribute = :subdomain
|
|
327
|
+
config.schema_prefix = Rails.env.production? ? nil : "#{Rails.env}_"
|
|
328
|
+
end
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Enterprise Application
|
|
332
|
+
```ruby
|
|
333
|
+
PgMultitenantSchemas.configure do |config|
|
|
334
|
+
config.default_schema = 'master'
|
|
335
|
+
config.tenant_model = 'Organization'
|
|
336
|
+
config.tenant_schema_attribute = :schema_name
|
|
337
|
+
config.connection_class = 'TenantRecord'
|
|
338
|
+
config.excluded_schemas += ['audit', 'analytics', 'logs']
|
|
339
|
+
end
|
|
340
|
+
```
|