From 0ffb83d351bd2b0ab66b4a4b22de2485acd84810 Mon Sep 17 00:00:00 2001
From: Benjamin Neff <benjamin@coding4coffee.ch>
Date: Thu, 4 Jun 2015 20:28:30 +0200
Subject: [PATCH] load conversations and visibilities in one query with correct
 order

---
 app/controllers/conversations_controller.rb | 46 ++++++++++++---------
 app/models/user.rb                          |  4 +-
 app/views/conversations/index.haml          |  2 +-
 3 files changed, 29 insertions(+), 23 deletions(-)

diff --git a/app/controllers/conversations_controller.rb b/app/controllers/conversations_controller.rb
index 7edf04aee1..278065734a 100644
--- a/app/controllers/conversations_controller.rb
+++ b/app/controllers/conversations_controller.rb
@@ -5,35 +5,41 @@ class ConversationsController < ApplicationController
   respond_to :html, :mobile, :json, :js
 
   def index
-    @conversations = current_user.conversations.paginate(
-      :page => params[:page], :per_page => 15)
-
-    @visibilities = current_user.conversation_visibilities.paginate(
-      :page => params[:page], :per_page => 15)
-
-    @conversation = Conversation.joins(:conversation_visibilities).where(
-      :conversation_visibilities => {:person_id => current_user.person_id, :conversation_id => params[:conversation_id]}).first
-
-    @unread_counts = {}
-    @visibilities.each { |v| @unread_counts[v.conversation_id] = v.unread }
-
-    @first_unread_message_id = @conversation.try(:first_unread_message, current_user).try(:id)
-
-    if @conversation
-      @conversation.set_read(current_user)
+    @visibilities = ConversationVisibility.includes(:conversation)
+                                          .order("conversations.updated_at DESC")
+                                          .where(person_id: current_user.person_id)
+                                          .paginate(page: params[:page], per_page: 15)
+
+    if params[:conversation_id]
+      @conversation = Conversation.joins(:conversation_visibilities)
+                                  .where(conversation_visibilities: {
+                                           person_id:       current_user.person_id,
+                                           conversation_id: params[:conversation_id]
+                                         }).first
+
+      if @conversation
+        @first_unread_message_id = @conversation.first_unread_message(current_user).try(:id)
+        @conversation.set_read(current_user)
+      end
     end
 
+    @conversations = []
+    @unread_counts = {}
     @authors = {}
-    @conversations.each { |c| @authors[c.id] = c.last_author }
-
     @ordered_participants = {}
-    @conversations.each { |c| @ordered_participants[c.id] = (c.messages.map{|m| m.author}.reverse + c.participants).uniq }
+    @visibilities.each {|v|
+      @unread_counts[v.conversation_id] = v.unread
+      c = v.conversation
+      @conversations << c
+      @authors[c.id] = c.last_author
+      @ordered_participants[c.id] = (c.messages.map(&:author).reverse + c.participants).uniq
+    }
 
     gon.contacts = contacts_data
 
     respond_with do |format|
       format.html
-      format.json { render :json => @conversations, :status => 200 }
+      format.json { render json: @conversations, status: 200 }
     end
   end
 
diff --git a/app/models/user.rb b/app/models/user.rb
index 8de37ecafa..bdcc1bc74c 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -67,8 +67,8 @@ class User < ActiveRecord::Base
   has_many :blocks
   has_many :ignored_people, :through => :blocks, :source => :person
 
-  has_many :conversation_visibilities, -> { order 'updated_at DESC' }, through: :person
-  has_many :conversations, -> { order 'updated_at DESC' }, through: :conversation_visibilities
+  has_many :conversation_visibilities, through: :person
+  has_many :conversations, through: :conversation_visibilities
 
   has_many :notifications, :foreign_key => :recipient_id
 
diff --git a/app/views/conversations/index.haml b/app/views/conversations/index.haml
index ecbcb6aff5..9f28747ad8 100644
--- a/app/views/conversations/index.haml
+++ b/app/views/conversations/index.haml
@@ -21,7 +21,7 @@
             - else
               #no_conversations
                 = t('.no_messages')
-            = will_paginate @conversations, :previous_label => '&laquo;', :next_label => '&raquo;', :inner_window => 1, :renderer => WillPaginate::ActionView::BootstrapLinkRenderer
+            = will_paginate @visibilities, :previous_label => "&laquo;", :next_label => "&raquo;", :inner_window => 1, :renderer => WillPaginate::ActionView::BootstrapLinkRenderer
 
     .span8
       - if @conversation
-- 
GitLab