Class: RailsOnboarding::MultiTenant
- Inherits:
-
Object
- Object
- RailsOnboarding::MultiTenant
- Defined in:
- lib/rails_onboarding/multi_tenant.rb
Overview
Multi-Tenant Support Allows different onboarding configurations per organization/tenant
Class Method Summary collapse
-
.clear_all_configurations ⇒ Object
Clear all organization configurations (useful for testing).
-
.configuration_for(tenant) ⇒ Hash
Get configuration for a specific tenant.
-
.configure_for_organization(organization_id) {|config| ... } ⇒ Object
Configure onboarding for a specific organization by ID.
-
.copy_configuration(source_tenant, target_tenant) ⇒ Object
Copy configuration from one tenant to another.
-
.feature_enabled?(tenant, feature) ⇒ Boolean
Check if a feature is enabled for a tenant.
-
.merged_configuration_cache ⇒ Object
Merged configuration is cached per organization ID so repeated lookups (every onboarding request) don't re-merge the same hash every time.
-
.milestones_for(tenant) ⇒ Array<Hash>
Get milestones for a specific tenant.
-
.organization_configurations ⇒ Object
Storage for organization-specific configurations (by ID).
-
.organization_for_user(user) ⇒ Integer, ...
Get organization ID for user.
-
.reset_configuration(tenant) ⇒ Object
Reset tenant configuration to default.
-
.set_configuration(tenant, config) ⇒ Object
Set custom configuration for a tenant.
-
.steps_for(tenant) ⇒ Array<Hash>
Get steps for a specific tenant.
-
.tenant_from_user(user) ⇒ Object?
Get tenant from user.
-
.tooltips_for(tenant) ⇒ Hash
Get feature tooltips for a specific tenant.
-
.with_tenant_configuration(tenant) { ... } ⇒ Object
Apply tenant configuration to current context, for the duration of the block only.
Class Method Details
.clear_all_configurations ⇒ Object
Clear all organization configurations (useful for testing)
30 31 32 33 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 30 def clear_all_configurations @organization_configurations = {} @merged_configuration_cache = {} end |
.configuration_for(tenant) ⇒ Hash
Get configuration for a specific tenant
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 39 def configuration_for(tenant) return default_configuration unless tenant # Check if tenant is an ID (for organization_configurations lookup) if tenant.is_a?(Integer) || tenant.is_a?(String) return merged_configuration_cache[tenant] ||= begin stored_config = organization_configurations[tenant] stored_config ? merge_configurations(default_configuration, stored_config) : default_configuration end end # Check if tenant has custom configuration tenant_config = if tenant.respond_to?(:onboarding_configuration) tenant.onboarding_configuration elsif tenant.respond_to?(:onboarding_config) tenant.onboarding_config end return default_configuration unless tenant_config # Merge with default configuration merge_configurations(default_configuration, parse_config(tenant_config)) end |
.configure_for_organization(organization_id) {|config| ... } ⇒ Object
Configure onboarding for a specific organization by ID
22 23 24 25 26 27 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 22 def configure_for_organization(organization_id) config = OrganizationConfig.new(organization_id) yield config if block_given? organization_configurations[organization_id] = config.to_hash merged_configuration_cache.delete(organization_id) end |
.copy_configuration(source_tenant, target_tenant) ⇒ Object
Copy configuration from one tenant to another
192 193 194 195 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 192 def copy_configuration(source_tenant, target_tenant) config = configuration_for(source_tenant) set_configuration(target_tenant, config) end |
.feature_enabled?(tenant, feature) ⇒ Boolean
Check if a feature is enabled for a tenant
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 95 def feature_enabled?(tenant, feature) config = configuration_for(tenant) case feature when :tooltips config[:enable_tooltips] != false when :milestones config[:enable_milestones] != false when :analytics config[:enable_analytics] != false when :ab_testing config[:enable_ab_testing] == true when :personalization config[:personalization_enabled] == true else false end end |
.merged_configuration_cache ⇒ Object
Merged configuration is cached per organization ID so repeated lookups (every onboarding request) don't re-merge the same hash every time. Invalidated whenever that organization is reconfigured or cleared.
14 15 16 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 14 def merged_configuration_cache @merged_configuration_cache ||= {} end |
.milestones_for(tenant) ⇒ Array<Hash>
Get milestones for a specific tenant
85 86 87 88 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 85 def milestones_for(tenant) config = configuration_for(tenant) config[:milestones] || RailsOnboarding.configuration.milestones end |
.organization_configurations ⇒ Object
Storage for organization-specific configurations (by ID)
7 8 9 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 7 def organization_configurations @organization_configurations ||= {} end |
.organization_for_user(user) ⇒ Integer, ...
Get organization ID for user
139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 139 def organization_for_user(user) return nil unless user # Try to get organization_id directly if user.respond_to?(:organization_id) return user.organization_id end # Otherwise, get tenant and extract its ID tenant = tenant_from_user(user) tenant&.id end |
.reset_configuration(tenant) ⇒ Object
Reset tenant configuration to default
200 201 202 203 204 205 206 207 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 200 def reset_configuration(tenant) return unless tenant if tenant.respond_to?(:onboarding_configuration=) tenant.onboarding_configuration = nil tenant.save end end |
.set_configuration(tenant, config) ⇒ Object
Set custom configuration for a tenant
177 178 179 180 181 182 183 184 185 186 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 177 def set_configuration(tenant, config) return unless tenant if tenant.respond_to?(:onboarding_configuration=) tenant.onboarding_configuration = config.to_json tenant.save elsif tenant.respond_to?(:update) tenant.update(onboarding_configuration: config.to_json) rescue nil end end |
.steps_for(tenant) ⇒ Array<Hash>
Get steps for a specific tenant
67 68 69 70 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 67 def steps_for(tenant) config = configuration_for(tenant) config[:steps] || RailsOnboarding.configuration.steps end |
.tenant_from_user(user) ⇒ Object?
Get tenant from user
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 156 def tenant_from_user(user) return nil unless user # Try common tenant associations if user.respond_to?(:organization) user.organization elsif user.respond_to?(:account) user.account elsif user.respond_to?(:tenant) user.tenant elsif user.respond_to?(:team) user.team elsif user.respond_to?(:company) user.company end end |
.tooltips_for(tenant) ⇒ Hash
Get feature tooltips for a specific tenant
76 77 78 79 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 76 def tooltips_for(tenant) config = configuration_for(tenant) config[:feature_tooltips] || RailsOnboarding.configuration.feature_tooltips end |
.with_tenant_configuration(tenant) { ... } ⇒ Object
Apply tenant configuration to current context, for the duration of the
block only. This does NOT touch RailsOnboarding.configuration itself -
it sets a thread/fiber-local override (RailsOnboarding::Current) that
Configuration's readers consult first, so concurrent requests for
other tenants (or no tenant) are never affected, and everything is
automatically cleared even if this method's own ensure never ran
(Rails resets CurrentAttributes around every request and job).
124 125 126 127 128 129 130 131 132 133 |
# File 'lib/rails_onboarding/multi_tenant.rb', line 124 def with_tenant_configuration(tenant) return yield unless tenant previous_overrides = RailsOnboarding::Current.tenant_overrides RailsOnboarding::Current.tenant_overrides = tenant_config_overrides(tenant) yield ensure RailsOnboarding::Current.tenant_overrides = previous_overrides end |