Commit ab738645 authored by Yorick Peterse's avatar Yorick Peterse

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.
parent 4a915c73
...@@ -632,7 +632,11 @@ class User < ActiveRecord::Base ...@@ -632,7 +632,11 @@ class User < ActiveRecord::Base
end end
def projects_limit_left 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 end
def projects_limit_percent def projects_limit_percent
......
---
title: Memoize the number of personal projects a user has to reduce COUNT queries
merge_request:
author:
...@@ -1976,4 +1976,28 @@ describe User do ...@@ -1976,4 +1976,28 @@ describe User do
expect(user.allow_password_authentication?).to be_falsey expect(user.allow_password_authentication?).to be_falsey
end end
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 end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment