diff options
author | Jarka Kadlecová <jarka@gitlab.com> | 2018-01-15 13:06:42 +0100 |
---|---|---|
committer | Jarka Kadlecová <jarka@gitlab.com> | 2018-01-15 13:06:42 +0100 |
commit | 4f83ef5a370bdae2b94f3fba963a100a68381dba (patch) | |
tree | 0a725113e51721bd38ec8f80415821911e721ad8 | |
parent | 2de8fb7bab49c1a5168ee56fc12e1f3ceb0ad1c7 (diff) | |
download | gitlab-ce-41958-events-performance.tar.gz |
Avoid N+1 queries when fetching events from the API41958-events-performance
-rw-r--r-- | changelogs/unreleased/41958-events-performance.yml | 5 | ||||
-rw-r--r-- | lib/api/events.rb | 8 | ||||
-rw-r--r-- | spec/requests/api/events_spec.rb | 18 |
3 files changed, 27 insertions, 4 deletions
diff --git a/changelogs/unreleased/41958-events-performance.yml b/changelogs/unreleased/41958-events-performance.yml new file mode 100644 index 00000000000..bcd52910e62 --- /dev/null +++ b/changelogs/unreleased/41958-events-performance.yml @@ -0,0 +1,5 @@ +--- +title: Avoid N+1 queries when fetching events from the API +merge_request: +author: +type: performance diff --git a/lib/api/events.rb b/lib/api/events.rb index b0713ff1d54..0787930f363 100644 --- a/lib/api/events.rb +++ b/lib/api/events.rb @@ -16,7 +16,7 @@ module API end def present_events(events) - events = events.reorder(created_at: params[:sort]) + events = events.preload(:author, :target, :noteable).reorder(created_at: params[:sort]) present paginate(events), with: Entities::Event end @@ -35,7 +35,7 @@ module API get do authenticate! - events = EventsFinder.new(params.merge(source: current_user, current_user: current_user)).execute.preload(:author, :target) + events = EventsFinder.new(params.merge(source: current_user, current_user: current_user)).execute present_events(events) end @@ -58,7 +58,7 @@ module API user = find_user(params[:id]) not_found!('User') unless user - events = EventsFinder.new(params.merge(source: user, current_user: current_user)).execute.preload(:author, :target) + events = EventsFinder.new(params.merge(source: user, current_user: current_user)).execute present_events(events) end @@ -77,7 +77,7 @@ module API use :sort_params end get ":id/events" do - events = EventsFinder.new(params.merge(source: user_project, current_user: current_user)).execute.preload(:author, :target) + events = EventsFinder.new(params.merge(source: user_project, current_user: current_user)).execute present_events(events) end diff --git a/spec/requests/api/events_spec.rb b/spec/requests/api/events_spec.rb index 962c845f36d..6696fb69273 100644 --- a/spec/requests/api/events_spec.rb +++ b/spec/requests/api/events_spec.rb @@ -160,6 +160,24 @@ describe API::Events do expect(json_response.size).to eq(1) end + it 'does not perform N+1 queries' do + endpoint = api("/projects/#{private_project.id}/events?action=closed", user) + + issue = create(:issue, project: private_project) + note = create(:note, project: private_project, noteable: issue) + create(:event, project:private_project, target: note, action: Event::CLOSED) + + control_count = ActiveRecord::QueryRecorder.new { get endpoint }.count + + issues = create_list(:issue, 5, project: private_project) + issues.each do |issue| + note = create(:note, project: private_project, noteable: issue) + create(:event, project:private_project, target: note, action: Event::CLOSED) + end + + expect { get endpoint }.not_to exceed_query_limit(control_count) + end + it 'returns 404 if project does not exist' do get api("/projects/1234/events", user) |