summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorSean McGivern <sean@gitlab.com>2019-03-07 10:29:04 +0000
committerSean McGivern <sean@gitlab.com>2019-03-07 10:29:04 +0000
commit3781cbe0c3e56067ce60f63f83d7e3d292a03403 (patch)
treefbdae8333ac916715076d3bc41ed25bcd3810bfb /app
parent5a75aa59dbafc8f0c25800f952df1e0aaa2d4dd5 (diff)
parent062efe4f7a83fb2b6d951b314692cca9ee8731cd (diff)
downloadgitlab-ce-3781cbe0c3e56067ce60f63f83d7e3d292a03403.tar.gz
Merge branch 'sh-optimize-todos-api' into 'master'
Significantly reduce N+1 queries in /api/v4/todos endpoint Closes #40378 See merge request gitlab-org/gitlab-ce!25711
Diffstat (limited to 'app')
-rw-r--r--app/models/issue.rb1
-rw-r--r--app/models/merge_request.rb7
-rw-r--r--app/models/todo.rb9
3 files changed, 16 insertions, 1 deletions
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 071ad50fddc..deab53d25e7 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -64,6 +64,7 @@ class Issue < ActiveRecord::Base
scope :order_closest_future_date, -> { reorder('CASE WHEN issues.due_date >= CURRENT_DATE THEN 0 ELSE 1 END ASC, ABS(CURRENT_DATE - issues.due_date) ASC') }
scope :preload_associations, -> { preload(:labels, project: :namespace) }
+ scope :with_api_entity_associations, -> { preload(:timelogs, :assignees, :author, :notes, :labels, project: [:route, { namespace: :route }] ) }
scope :public_only, -> { where(confidential: false) }
scope :confidential_only, -> { where(confidential: true) }
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index b67797f5404..acf80addc6a 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -184,6 +184,13 @@ class MergeRequest < ActiveRecord::Base
scope :assigned, -> { where("assignee_id IS NOT NULL") }
scope :unassigned, -> { where("assignee_id IS NULL") }
scope :assigned_to, ->(u) { where(assignee_id: u.id)}
+ scope :with_api_entity_associations, -> {
+ preload(:author, :assignee, :notes, :labels, :milestone, :timelogs,
+ latest_merge_request_diff: [:merge_request_diff_commits],
+ metrics: [:latest_closed_by, :merged_by],
+ target_project: [:route, { namespace: :route }],
+ source_project: [:route, { namespace: :route }])
+ }
participant :assignee
diff --git a/app/models/todo.rb b/app/models/todo.rb
index d9b86d941b6..2b0dee875a3 100644
--- a/app/models/todo.rb
+++ b/app/models/todo.rb
@@ -31,7 +31,13 @@ class Todo < ActiveRecord::Base
belongs_to :note
belongs_to :project
belongs_to :group
- belongs_to :target, polymorphic: true, touch: true # rubocop:disable Cop/PolymorphicAssociations
+ belongs_to :target, -> {
+ if self.klass.respond_to?(:with_api_entity_associations)
+ self.with_api_entity_associations
+ else
+ self
+ end
+ }, polymorphic: true, touch: true # rubocop:disable Cop/PolymorphicAssociations
belongs_to :user
delegate :name, :email, to: :author, prefix: true, allow_nil: true
@@ -52,6 +58,7 @@ class Todo < ActiveRecord::Base
scope :for_type, -> (type) { where(target_type: type) }
scope :for_target, -> (id) { where(target_id: id) }
scope :for_commit, -> (id) { where(commit_id: id) }
+ scope :with_api_entity_associations, -> { preload(:target, :author, :note, group: :route, project: [:route, { namespace: :route }]) }
state_machine :state, initial: :pending do
event :done do