summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2017-08-04 16:43:01 +0200
committerYorick Peterse <yorickpeterse@gmail.com>2017-08-07 12:38:32 +0200
commitab738645a7b5bba46c8bf50f0780e66befc8bbe2 (patch)
treea053f0114731ec4c759171cd83dcb6468fefa03a
parent4a915c739d502a8b1d2a019f4352d46a3be3d7e0 (diff)
downloadgitlab-ce-ab738645a7b5bba46c8bf50f0780e66befc8bbe2.tar.gz
Memoize a user's personal projects count
The method User#projects_limit_left would run "personal_projects.count" but such a query is not memoized. As a result multiple calls to User#projects_limit_left would result in multiple COUNT(*) queries being executed. To work around this this commit adds User#personal_projects_count which simply memoizes the result of the COUNT(*) in an instance variable.
-rw-r--r--app/models/user.rb6
-rw-r--r--changelogs/unreleased/memoize-user-personal-projects-count.yml4
-rw-r--r--spec/models/user_spec.rb24
3 files changed, 33 insertions, 1 deletions
diff --git a/app/models/user.rb b/app/models/user.rb
index afcadfe484e..5148886eed7 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -632,7 +632,11 @@ class User < ActiveRecord::Base
end
def projects_limit_left
- projects_limit - personal_projects.count
+ projects_limit - personal_projects_count
+ end
+
+ def personal_projects_count
+ @personal_projects_count ||= personal_projects.count
end
def projects_limit_percent
diff --git a/changelogs/unreleased/memoize-user-personal-projects-count.yml b/changelogs/unreleased/memoize-user-personal-projects-count.yml
new file mode 100644
index 00000000000..3839a97f185
--- /dev/null
+++ b/changelogs/unreleased/memoize-user-personal-projects-count.yml
@@ -0,0 +1,4 @@
+---
+title: Memoize the number of personal projects a user has to reduce COUNT queries
+merge_request:
+author:
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index a6bd6052006..0103fb6040e 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1976,4 +1976,28 @@ describe User do
expect(user.allow_password_authentication?).to be_falsey
end
end
+
+ describe '#personal_projects_count' do
+ it 'returns the number of personal projects using a single query' do
+ user = build(:user)
+ projects = double(:projects, count: 1)
+
+ expect(user).to receive(:personal_projects).once.and_return(projects)
+
+ 2.times do
+ expect(user.personal_projects_count).to eq(1)
+ end
+ end
+ end
+
+ describe '#projects_limit_left' do
+ it 'returns the number of projects that can be created by the user' do
+ user = build(:user)
+
+ allow(user).to receive(:projects_limit).and_return(10)
+ allow(user).to receive(:personal_projects_count).and_return(5)
+
+ expect(user.projects_limit_left).to eq(5)
+ end
+ end
end