2013-07-17 29 views
0

我使用名爲「郵箱」的郵件(https://github.com/ging/mailboxer
這使Rails應用程序內的郵件系統成爲可能。這爲什麼這麼慢加載?有沒有什麼技術可以讓這個更快?

有了這個寶石,我顯示了每個頁面收到10封郵件。
我在這裏使用Kaminari進行分頁。

但是,我的代碼太慢了。 它的發行超過25 SQL一下子:( 我怎樣才能使這個快?這需要超過1500毫秒以上,顯示僅有1頁。

這裏是我的代碼 這有什麼錯呢?有沒有什麼技術,使此快?

控制器

@number_of_messages_to_display = 10 
@messages = current_user.mailbox.inbox.page(params[:page]).per(@number_of_messages_to_display) 
@messages_count = current_user.mailbox.inbox.count 

視圖(消息/ index.html.erb)

<%= @messages_count.to_s %> messages in your received message box. 

<table> 
    <% @messages.each do |m| %> 
     <tr> 
      <td><%= check_box_tag "id[]",m.id %></td> 
      <td><%= if m.is_read?(current_user) then "Read" else "Un-read" %></td> 
      <td><%= profile_link(m.recipients.first) if m.recipients.first != current_user %></td> 
      <td><%= link_to m.subject, show_messages_path(:id => m) %></td> 
      <td><%= today_datetime(m.last_message.created_at) %></td> 
     </tr> 
    <% end %> 
</table> 

視圖(助手/ application_helper.rb)

def profile_link(user) 
    if user 
     nickname = user.user_profile.try(:nickname) 
     username = user.try(:username) 
     link_to nickname, show_user_path(username) 
    else 
     "Un-known" 
    end 
end 

def today_datetime(date_time) 
    date_time.to_date == Date.current.to_date ? "<span class='text-info'>#{date_time.to_s(:us)}</span>".html_safe : date_time.to_s(:us) 
end 

的routes.rb

get 'messages/:id' => 'messages#show', :as => :show_messages 
get "users/:id" => 'users#show', :as => :show_user 

模型/ user.rb

def to_param 
    "#{username}" 
end 

回答

0

經典示例N + 1 problem.

您檢索@messages = current_user.mailbox.inbox.page,它將從messages表中檢索記錄。

在視圖,通過他們你循環,並檢查每封郵件的recipients列表( 一個 has_many關係,可能 基礎上,receipts表,可以看出here)。因此,對於每條消息,您最終將向數據庫發送另一個查詢。

您可以通過檢索收件人與信息一起(和last_message協會爲好,因爲你使用它)糾正這一點,

@messages = current_user.mailbox.inbox. 
    includes(:receipt, :last_message).page 

此外,您還可能有不同的問題,這個複合,因爲25個查詢應該在現代計算機上很快執行。我建議使用類似RailsPanel工具的東西來追蹤時間花在哪裏。

+0

謝謝我試圖用你的代碼替換我的代碼。但現在它說這個錯誤'ActionView :: Template :: Error(沒有找到名爲'recipients'的關聯;也許你拼錯了它?):' – MKK

+0

你可以看看gem的來源,包括ActiveRecord模型, github](https://github.com/ging/mailboxer/tree/master/app/models)。在這種情況下,'recipients'是一個屬性,並且基於從'Notification'模型繼承的'has_many:receipts'關係。 – bdares

+0

謝謝。你能弄清楚爲什麼你的代碼不能正常工作嗎?你知道寶石叫做「子彈」嗎?我試着用這個頁面。但沒有警報彈出:( – MKK