summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarka Kadlecová <jarka@gitlab.com>2018-01-15 13:06:42 +0100
committerJarka Kadlecová <jarka@gitlab.com>2018-01-15 13:06:42 +0100
commit4f83ef5a370bdae2b94f3fba963a100a68381dba (patch)
tree0a725113e51721bd38ec8f80415821911e721ad8
parent2de8fb7bab49c1a5168ee56fc12e1f3ceb0ad1c7 (diff)
downloadgitlab-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.yml5
-rw-r--r--lib/api/events.rb8
-rw-r--r--spec/requests/api/events_spec.rb18
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)