organizations 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 +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +2 -15
- data/lib/generators/organizations/install/templates/create_organizations_tables.rb.erb +1 -0
- data/lib/organizations/models/membership.rb +2 -34
- data/lib/organizations/models/organization.rb +3 -6
- data/lib/organizations/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3489dee0ace79d490d899aa756462b26d367d2f609ca58b2ff96b41326a58ab1
|
|
4
|
+
data.tar.gz: 6764004c3e0fc2524eee6b457f8384de50ce9d4117b414eca9ba4519316e202b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 88518342c7bcc6cc8c75eb83a036ac08348fc83962ba5f78e536deb22eedf1a1bfcc44c72255afe4e9b3080d6e8657133125ece9c87da21db583e1888eae09f5
|
|
7
|
+
data.tar.gz: d1f4aafce6fd17500d9f287b7907b165b4faee6a9fc219472f22a68fc06cabfb9cb82907184f6bf8530660fb89f3df7c449651cbc32217a168e0ddb7eb0c6d67
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## [0.4.0] - 2026-03-17
|
|
2
|
+
|
|
3
|
+
**Breaking:** `memberships_count` column is now required on the organizations table.
|
|
4
|
+
|
|
5
|
+
- Added `memberships_count` to the install migration template (fresh installs get it automatically)
|
|
6
|
+
- Switched to Rails' native `counter_cache` so in-memory organization instances stay accurate after member changes
|
|
7
|
+
- `member_count` now reads directly from the counter cache (no fallback to COUNT query)
|
|
8
|
+
- Marked `memberships_count` as readonly on organizations
|
|
9
|
+
|
|
1
10
|
## [0.3.1] - 2026-02-28
|
|
2
11
|
|
|
3
12
|
- Fixed `organization_switcher_data[:switch_path]` generating broken URLs when engine mounted with custom name (e.g., `as: 'organizations_engine'`)
|
data/README.md
CHANGED
|
@@ -1387,24 +1387,11 @@ organization_switcher_data
|
|
|
1387
1387
|
|
|
1388
1388
|
### Counter caches for member counts
|
|
1389
1389
|
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
```ruby
|
|
1393
|
-
# In a migration
|
|
1394
|
-
add_column :organizations_organizations, :memberships_count, :integer, default: 0, null: false
|
|
1395
|
-
|
|
1396
|
-
# Reset existing counts
|
|
1397
|
-
Organization.find_each do |org|
|
|
1398
|
-
Organization.reset_counters(org.id, :memberships)
|
|
1399
|
-
end
|
|
1400
|
-
```
|
|
1401
|
-
|
|
1402
|
-
The gem automatically uses the counter cache if present:
|
|
1390
|
+
The install migration includes a `memberships_count` counter cache on organizations, and `member_count` reads from it directly:
|
|
1403
1391
|
|
|
1404
1392
|
```ruby
|
|
1405
1393
|
org.member_count
|
|
1406
|
-
# Uses memberships_count
|
|
1407
|
-
# Falls back to COUNT(*) query otherwise
|
|
1394
|
+
# Uses the memberships_count counter cache
|
|
1408
1395
|
```
|
|
1409
1396
|
|
|
1410
1397
|
### Existence checks use SQL
|
|
@@ -8,6 +8,7 @@ class CreateOrganizationsTables < ActiveRecord::Migration<%= migration_version %
|
|
|
8
8
|
# Organizations table
|
|
9
9
|
create_table :organizations_organizations, id: primary_key_type do |t|
|
|
10
10
|
t.string :name, null: false
|
|
11
|
+
t.integer :memberships_count, default: 0, null: false
|
|
11
12
|
t.send(json_column_type, :metadata, null: json_column_null, default: json_column_default)
|
|
12
13
|
|
|
13
14
|
t.timestamps
|
|
@@ -28,7 +28,8 @@ module Organizations
|
|
|
28
28
|
belongs_to :user
|
|
29
29
|
belongs_to :organization,
|
|
30
30
|
class_name: "Organizations::Organization",
|
|
31
|
-
inverse_of: :memberships
|
|
31
|
+
inverse_of: :memberships,
|
|
32
|
+
counter_cache: :memberships_count
|
|
32
33
|
|
|
33
34
|
belongs_to :invited_by,
|
|
34
35
|
class_name: "User",
|
|
@@ -40,11 +41,6 @@ module Organizations
|
|
|
40
41
|
validates :user_id, uniqueness: { scope: :organization_id, message: "is already a member of this organization" }
|
|
41
42
|
validate :single_owner_per_organization, if: :owner?
|
|
42
43
|
|
|
43
|
-
# Keep memberships_count accurate when the optional counter cache column exists.
|
|
44
|
-
after_create_commit :increment_memberships_counter_cache
|
|
45
|
-
after_destroy_commit :decrement_memberships_counter_cache
|
|
46
|
-
after_update_commit :sync_memberships_counter_cache_for_org_change, if: :saved_change_to_organization_id?
|
|
47
|
-
|
|
48
44
|
# === Scopes ===
|
|
49
45
|
|
|
50
46
|
# Memberships with owner role
|
|
@@ -200,34 +196,6 @@ module Organizations
|
|
|
200
196
|
errors.add(:role, "owner already exists for this organization")
|
|
201
197
|
end
|
|
202
198
|
|
|
203
|
-
def increment_memberships_counter_cache
|
|
204
|
-
return unless memberships_counter_cache_enabled?
|
|
205
|
-
return unless organization_id
|
|
206
|
-
|
|
207
|
-
Organizations::Organization.increment_counter(:memberships_count, organization_id)
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
def decrement_memberships_counter_cache
|
|
211
|
-
return unless memberships_counter_cache_enabled?
|
|
212
|
-
return unless organization_id
|
|
213
|
-
|
|
214
|
-
Organizations::Organization.decrement_counter(:memberships_count, organization_id)
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
def sync_memberships_counter_cache_for_org_change
|
|
218
|
-
return unless memberships_counter_cache_enabled?
|
|
219
|
-
|
|
220
|
-
old_org_id, new_org_id = saved_change_to_organization_id
|
|
221
|
-
Organizations::Organization.decrement_counter(:memberships_count, old_org_id) if old_org_id
|
|
222
|
-
Organizations::Organization.increment_counter(:memberships_count, new_org_id) if new_org_id
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
def memberships_counter_cache_enabled?
|
|
226
|
-
Organizations::Organization.column_names.include?("memberships_count")
|
|
227
|
-
rescue StandardError
|
|
228
|
-
false
|
|
229
|
-
end
|
|
230
|
-
|
|
231
199
|
def validate_role!(role)
|
|
232
200
|
unless Roles.valid_role?(role)
|
|
233
201
|
raise ArgumentError, "Invalid role: #{role}. Must be one of: #{Roles.valid_roles.join(', ')}"
|
|
@@ -46,6 +46,7 @@ module Organizations
|
|
|
46
46
|
# === Validations ===
|
|
47
47
|
|
|
48
48
|
validates :name, presence: true
|
|
49
|
+
attr_readonly :memberships_count
|
|
49
50
|
|
|
50
51
|
# === Scopes ===
|
|
51
52
|
|
|
@@ -101,14 +102,10 @@ module Organizations
|
|
|
101
102
|
memberships.exists?
|
|
102
103
|
end
|
|
103
104
|
|
|
104
|
-
# Get member count
|
|
105
|
+
# Get member count from the organizations counter cache.
|
|
105
106
|
# @return [Integer]
|
|
106
107
|
def member_count
|
|
107
|
-
|
|
108
|
-
self[:memberships_count] || memberships.count
|
|
109
|
-
else
|
|
110
|
-
memberships.count
|
|
111
|
-
end
|
|
108
|
+
memberships_count || 0
|
|
112
109
|
end
|
|
113
110
|
|
|
114
111
|
# Get pending invitations
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: organizations
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- rameerez
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-03-17 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: railties
|