From a5f23435f7d8b8040ed6b80322ccea3fa8323468 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Wed, 24 Jun 2015 12:49:34 +0200
Subject: [PATCH] Improve performance for issue#show page

* store @participants in variable
* store result of subscribed? call into variable

In total it reduce amount of SQL queries for issue with 10 comments/participants twice.

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
---
 app/controllers/projects/issues_controller.rb      | 1 +
 app/models/concerns/participable.rb                | 8 +++++---
 app/views/projects/issues/_discussion.html.haml    | 4 ++--
 app/views/projects/issues/_issue_context.html.haml | 9 +++++----
 4 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 7d168aa827b..69bd1f58449 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -55,6 +55,7 @@ class Projects::IssuesController < Projects::ApplicationController
   end
 
   def show
+    @participants = @issue.participants(current_user, @project)
     @note = @project.notes.new(noteable: @issue)
     @notes = @issue.notes.inc_author.fresh
     @noteable = @issue
diff --git a/app/models/concerns/participable.rb b/app/models/concerns/participable.rb
index 9f667f47e0d..7c9597333dd 100644
--- a/app/models/concerns/participable.rb
+++ b/app/models/concerns/participable.rb
@@ -14,7 +14,7 @@
 #
 #       participant :author, :assignee, :mentioned_users, :notes
 #     end
-#     
+#
 #     issue = Issue.last
 #     users = issue.participants
 #     # `users` will contain the issue's author, its assignee,
@@ -35,11 +35,13 @@ module Participable
     end
   end
 
+  # Be aware that this method makes a lot of sql queries.
+  # Save result into variable if you are going to reuse it inside same request
   def participants(current_user = self.author, project = self.project)
     participants = self.class.participant_attrs.flat_map do |attr|
       meth = method(attr)
 
-      value = 
+      value =
         if meth.arity == 1 || meth.arity == -1
           meth.call(current_user)
         else
@@ -59,7 +61,7 @@ module Participable
   end
 
   private
-  
+
   def participants_for(value, current_user = nil, project = nil)
     case value
     when User
diff --git a/app/views/projects/issues/_discussion.html.haml b/app/views/projects/issues/_discussion.html.haml
index 48858fa32da..656e06ca105 100644
--- a/app/views/projects/issues/_discussion.html.haml
+++ b/app/views/projects/issues/_discussion.html.haml
@@ -12,8 +12,8 @@
     .votes-holder.pull-right
       #votes= render 'votes/votes_block', votable: @issue
     .participants
-      %span= pluralize(@issue.participants(current_user).count, 'participant')
-      - @issue.participants(current_user).each do |participant|
+      %span= pluralize(@participants.count, 'participant')
+      - @participants.each do |participant|
         = link_to_member(@project, participant, name: false, size: 24)
     .voting_notes#notes= render 'projects/notes/notes_with_form'
   %aside.col-md-3
diff --git a/app/views/projects/issues/_issue_context.html.haml b/app/views/projects/issues/_issue_context.html.haml
index 323f5c84a85..88b63946905 100644
--- a/app/views/projects/issues/_issue_context.html.haml
+++ b/app/views/projects/issues/_issue_context.html.haml
@@ -28,18 +28,19 @@
       = f.submit class: 'btn'
 
   - if current_user
+    - subscribed = @issue.subscribed?(current_user)
     %div.prepend-top-20.clearfix
       .issuable-context-title
         %label
           Subscription:
       %button.btn.btn-block.subscribe-button{:type => 'button'}
         %i.fa.fa-eye
-        %span= @issue.subscribed?(current_user) ? "Unsubscribe" : "Subscribe"
-      - subscribtion_status = @issue.subscribed?(current_user) ? "subscribed" : "unsubscribed"
+        %span= subscribed ? "Unsubscribe" : "Subscribe"
+      - subscribtion_status = subscribed ? "subscribed" : "unsubscribed"
       .subscription-status{"data-status" => subscribtion_status}
-        .description-block.unsubscribed{class: ( "hidden" if @issue.subscribed?(current_user) )}
+        .description-block.unsubscribed{class: ( "hidden" if subscribed )}
           You're not receiving notifications from this thread.
-        .description-block.subscribed{class: ( "hidden" unless @issue.subscribed?(current_user) )}
+        .description-block.subscribed{class: ( "hidden" unless subscribed )}
           You're receiving notifications because you're subscribed to this thread.
 
 :coffeescript
-- 
GitLab