Your question is Optimize Existing Code. Take a moment with it on the right.
Talk me through your thinking if you like. When you're confident, submit your answer and I'll grade it like a real screen (7/10 or better passes).
This is a simplified version of a GitLab-style backend service that summarizes merge request activity for a project: which merge requests are open, which have gone stale, who's been approving things, and nudging stale authors by email. On a busy self-managed instance with a lot of history, calling any of these methods takes noticeably longer than it should.
class MergeRequestService
def initialize(project)
@project = project
end
def open_merge_requests
MergeRequest.all.select { |mr| mr.project_id == @project.id && mr.status == "open" }
end
def stale_merge_requests(days = 14)
open_merge_requests.select do |mr|
(Time.now - mr.updated_at) / 86400 > days
end
end
def approvers_summary
summary = {}
open_merge_requests.each do |mr|
mr.approvals.each do |approval|
user = User.find(approval.user_id)
summary[user.username] ||= 0
summary[user.username] += 1
end
end
summary
end
def notify_stale_authors
stale_merge_requests.each do |mr|
author = User.find(mr.author_id)
NotificationMailer.stale_mr_warning(author.email, mr.title).deliver_now
end
end
end
What optimizations can be done with this code? Explain where the cost is actually coming from.