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