删除/重构以避免N + 1

时间:2015-10-20 15:00:55

标签: ruby-on-rails

我遇到了一个问题,即我在以下问题上遇到了大量的N + 1问题:

<% @reports.each do |report| %>
  <% (@first_week..@current_week).each do |week_number| %>
    <% if report.user.answers.where(week_number: @current_week).exists? %>
        <%= image_tag report.user.avatar.url(:thumb), size: '30', class: 'img-circle media-object' %>
        <%= link_to "#{report.user.first_name + ' ' + report.user.last_name}", weekly_report_path(report.user.id, week_number) %>
        <%= report.user.due_date %>
        <%= week_number %>
    <% end %>
  <% end %>
<% end %>

正如您所看到的那样,彼此之间存在大量关联,而我正试图找到一种简化此方法的方法。

控制器代码为:

  def index
    @reports      = current_user.active_managements
    @current_week = Time.zone.now.strftime('%V').to_i
    @first_week   = current_user.created_at.strftime('%V').to_i
  end

如何在这里避免N + 1问题,代码是否正常,只需要急切加载或者我应该重写 - 如果有的话,是否有任何建议?

我得到的子弹错误是:

  Reviewer => [:user]
  Add to your finder: :includes => [:user]
  index:15 which is:
  <% if report.user.answers.where(week_number: @current_week).exists? %>



  User => [:company]
  Add to your finder: :includes => [:company]
  navigation_links:21 which is:
<li><%= link_to "Settings", edit_company_path(current_user.company) %></li>

为行

1 个答案:

答案 0 :(得分:1)

由于信息有限,我会快速捅一下:

在您的控制器中,您需要急切加载用户及其答案:

@reports = current_user.active_managements.includes(user: [:answers, :avatar] )

在视图中,您需要更改“&#39; where&#39;检测并循环通过预先加载的对象。注意:这还没有经过测试,我只是在试一试。我希望它能让你走上正确的道路:

<% @reports.each do |report| %>
  <% (@first_week..@current_week).each do |week_number| %>
    <% if report.user.answers.detect { |a| a.week_number == @current_week.to_s}.present? %>
        <%= image_tag report.user.avatar.url(:thumb), size: '30', class: 'img-circle media-object' %>
        <%= link_to "#{report.user.first_name + ' ' + report.user.last_name}", weekly_report_path(report.user.id, week_number) %>
        <%= report.user.due_date %>
        <%= week_number %>
    <% end %>
  <% end %>
<% end %>