rls_multi_tenant 0.3.1 → 0.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e6d7f69028c0e956fc4d5caf7651dd885c4a9da43bed16a2d32e90c8177c7c9
4
- data.tar.gz: 5c8d3042cf29d8a21aad002e16db1193d2d0e8b7fea7246e4766116e81d301f9
3
+ metadata.gz: 9380863d6f5f1f68de3a4beaa1569cd6ad94bb5536604e0a444822628b946feb
4
+ data.tar.gz: eecebe1cecb827ed406b161f566de19d3effb7e8a96d73ebd497209b158e1c8b
5
5
  SHA512:
6
- metadata.gz: c35648de09e3f93962337d09fa699edc696a822924e19b046c1a2d6ae47663f4759f8e4c0541f1001c71f11f3b975827a7048e685082838f184c6f2becd33d9c
7
- data.tar.gz: f7148ffd7576d6cc20ca513cfa92c6d21c9890dbbcacd9fcd9c42b755deba2ee584d0de8c88e644d019370944451d4797e2cba72e1c09e89866b3b33a779ff6d
6
+ metadata.gz: faeb27cf2559a330bf13294cea3b114d017cb77d9c6e9af95acba26572bbf2016f6ffe2f8fb0dc67b1e731205f34f4ff0c69a4a592a91d6ec5d8b2c68127a211
7
+ data.tar.gz: 3fb38ae302313ed9845e86f3120c267ae88ad3e8eea793355f36db359ad316f6eaaac11805d21696a0b940ce54ba755cf5b4c5fdb7741066f1bd5b60fc236726
data/.rubocop.yml CHANGED
@@ -37,6 +37,7 @@ Metrics/MethodLength:
37
37
  Max: 25
38
38
 
39
39
  Metrics/ModuleLength:
40
+ Max: 120
40
41
  Exclude:
41
42
  - 'spec/**/*'
42
43
 
data/CHANGELOG.md CHANGED
@@ -5,6 +5,17 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.4.0] - 2026-06-04
9
+
10
+ ### Added
11
+
12
+ - **Apartment-style switching by a unique field.** `Tenant.switch_by(value)`
13
+ resolves the tenant by a unique column (defaulting to the configured
14
+ `subdomain_field`) and switches context for the block; pass `attribute:` to
15
+ use another column (e.g. `switch_by('acme', attribute: :slug)`). A permanent
16
+ `switch_by!` variant is also available. Both raise `RlsMultiTenant::Error`
17
+ when no tenant matches. Instance-level delegators are provided too.
18
+
8
19
  ## [0.3.1] - 2026-06-04
9
20
 
10
21
  Corrects two bugs in the 0.3.0 security work, both uncovered by a new
data/README.md CHANGED
@@ -152,6 +152,29 @@ Tenant.reset! # Reset context
152
152
  current_tenant = Tenant.current
153
153
  ```
154
154
 
155
+ #### Switching by a unique field (Apartment-style)
156
+
157
+ Instead of a tenant object or id, switch by any unique column. The attribute
158
+ defaults to the configured `subdomain_field`:
159
+
160
+ ```ruby
161
+ # Switch by subdomain (default field) for a block
162
+ Tenant.switch_by("company-a") do
163
+ User.create!(name: "User from Company A")
164
+ end
165
+
166
+ # Switch by another unique column
167
+ Tenant.switch_by("acme-inc", attribute: :slug) do
168
+ # ...
169
+ end
170
+
171
+ # Permanent variant (until reset!)
172
+ Tenant.switch_by!("company-a")
173
+ Tenant.reset!
174
+ ```
175
+
176
+ `switch_by` raises `RlsMultiTenant::Error` when no tenant matches the value.
177
+
155
178
  ### Automatic Subdomain-Based Tenant Switching
156
179
 
157
180
  The gem includes middleware that automatically switches tenants based on the request subdomain. This is enabled by default and works seamlessly with your tenant model.
@@ -60,6 +60,20 @@ module RlsMultiTenant
60
60
  apply_tenant_context(tenant_id, local: false)
61
61
  end
62
62
 
63
+ # Switch tenant context for a block, identifying the tenant by a unique
64
+ # field (Apartment-style). Defaults to the configured subdomain field.
65
+ #
66
+ # Tenant.switch_by('acme') { ... } # by subdomain
67
+ # Tenant.switch_by('acme', attribute: :slug) { } # by another column
68
+ def switch_by(value, attribute: RlsMultiTenant.subdomain_field, &block)
69
+ switch(find_tenant_by!(attribute, value), &block)
70
+ end
71
+
72
+ # Permanent variant of switch_by (until reset). Same caveats as switch!.
73
+ def switch_by!(value, attribute: RlsMultiTenant.subdomain_field)
74
+ switch!(find_tenant_by!(attribute, value))
75
+ end
76
+
63
77
  # Reset tenant context
64
78
  def reset!
65
79
  connection.execute format(RESET_TENANT_ID_SQL, tenant_session_var)
@@ -81,6 +95,15 @@ module RlsMultiTenant
81
95
 
82
96
  private
83
97
 
98
+ # Look up a tenant by a unique attribute, raising if none matches.
99
+ def find_tenant_by!(attribute, value)
100
+ tenant = RlsMultiTenant.tenant_class.find_by(attribute => value)
101
+ return tenant if tenant
102
+
103
+ raise RlsMultiTenant::Error,
104
+ "#{RlsMultiTenant.tenant_class_name} with #{attribute}=#{value.inspect} not found"
105
+ end
106
+
84
107
  # Restore the previous context on the way out of a `switch` block.
85
108
  # If the block aborted the transaction (e.g. a policy violation), any
86
109
  # further statement raises until rollback; that rollback will clear the
@@ -142,8 +165,14 @@ module RlsMultiTenant
142
165
  self.class.switch(tenant_or_id, &block)
143
166
  end
144
167
 
168
+ def switch_by(value, attribute: RlsMultiTenant.subdomain_field, &block)
169
+ self.class.switch_by(value, attribute: attribute, &block)
170
+ end
171
+
145
172
  delegate :switch!, to: :class
146
173
 
174
+ delegate :switch_by!, to: :class
175
+
147
176
  delegate :reset!, to: :class
148
177
  end
149
178
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RlsMultiTenant
4
- VERSION = '0.3.1'
4
+ VERSION = '0.4.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rls_multi_tenant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Coding Ways