summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Miller <travis@travismiller.com>2017-08-21 17:42:03 -0500
committerTravis Miller <travis@travismiller.com>2017-08-29 08:31:36 -0500
commitce1ce82045f168143ccc143f5200ea9da820d990 (patch)
tree05fc45a355aa94127a51d8a8952e785453fd7595
parent2531fb3be9542c08231a6540a14b12d907b151e5 (diff)
downloadgitlab-ce-ce1ce82045f168143ccc143f5200ea9da820d990.tar.gz
Resolve new N+1 by adding preloads and metadata to issues end points
-rw-r--r--lib/api/entities.rb22
-rw-r--r--lib/api/issues.rb22
2 files changed, 39 insertions, 5 deletions
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index e8dd61e493f..e18c69b7a3d 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -320,7 +320,10 @@ module API
end
class IssueBasic < ProjectEntity
- expose :label_names, as: :labels
+ expose :labels do |issue, options|
+ # Avoids an N+1 query since labels are preloaded
+ issue.labels.map(&:title).sort
+ end
expose :milestone, using: Entities::Milestone
expose :assignees, :author, using: Entities::UserBasic
@@ -329,7 +332,22 @@ module API
end
expose :user_notes_count
- expose :upvotes, :downvotes
+ expose :upvotes do |issue, options|
+ if options[:issuable_metadata]
+ # Avoids an N+1 query when metadata is included
+ options[:issuable_metadata][issue.id].upvotes
+ else
+ issue.upvotes
+ end
+ end
+ expose :downvotes do |issue, options|
+ if options[:issuable_metadata]
+ # Avoids an N+1 query when metadata is included
+ options[:issuable_metadata][issue.id].downvotes
+ else
+ issue.downvotes
+ end
+ end
expose :due_date
expose :confidential
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index 4cec1145f3a..64a425eb96e 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -4,6 +4,8 @@ module API
before { authenticate! }
+ helpers ::Gitlab::IssuableMetadata
+
helpers do
def find_issues(args = {})
args = params.merge(args)
@@ -13,6 +15,7 @@ module API
args[:label_name] = args.delete(:labels)
issues = IssuesFinder.new(current_user, args).execute
+ .preload(:assignees, :labels, :notes)
issues.reorder(args[:order_by] => args[:sort])
end
@@ -65,7 +68,11 @@ module API
get do
issues = find_issues
- present paginate(issues), with: Entities::IssueBasic, current_user: current_user
+ options = { with: Entities::IssueBasic,
+ current_user: current_user }
+ options[:issuable_metadata] = issuable_meta_data(issues, 'Issue')
+
+ present paginate(issues), options
end
end
@@ -86,7 +93,11 @@ module API
issues = find_issues(group_id: group.id)
- present paginate(issues), with: Entities::IssueBasic, current_user: current_user
+ options = { with: Entities::IssueBasic,
+ current_user: current_user }
+ options[:issuable_metadata] = issuable_meta_data(issues, 'Issue')
+
+ present paginate(issues), options
end
end
@@ -109,7 +120,12 @@ module API
issues = find_issues(project_id: project.id)
- present paginate(issues), with: Entities::IssueBasic, current_user: current_user, project: user_project
+ options = { with: Entities::IssueBasic,
+ current_user: current_user,
+ project: user_project }
+ options[:issuable_metadata] = issuable_meta_data(issues, 'Issue')
+
+ present paginate(issues), options
end
desc 'Get a single project issue' do