0

我正在使用名为“Mailboxer”(https://github.com/ging/mailboxer)的 gem,
这可以在 Rails 应用程序中启用消息传递系统。

有了这个 gem,我会为每个页面显示 10 条收到的消息。
我在这里使用 Kaminari 进行分页。

但是,我的代码有点太慢了。它一次发出超过 25 个 sql :( 我怎样才能让它更快?只显示 1 页需要超过 1500 毫秒。

这是我的代码这有什么问题?有什么技术可以让这更快吗?

控制器

@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

路线.rb

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

模型/用户.rb

def to_param
  "#{username}"
end
4

1 回答 1

0

N + 1问题的经典示例。

您检索@messages = current_user.mailbox.inbox.page,这将从messages表中检索记录。

在视图中,您遍历它们并检查每条消息的recipients列表(一种has_many关系,可能基于receipts表,如此处所示。因此,对于每条消息,您最终都会向数据库发送另一个查询。

您可以通过检索收件人以及消息(以及last_message关联,因为您正在使用它)来纠正此问题:

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

此外,您可能会遇到一个不同的问题,因为在现代计算机上应该可以快速执行 25 个查询。我建议使用 RailsPanel 工具之类的工具来跟踪花费的时间。

于 2013-07-17T07:55:54.037 回答