如何避免Rails中的N + 1个查询"每个"循环?

时间:2014-09-30 02:59:07

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-4 rails-activerecord

在todo列表式应用程序中,我有以下ActiveRecord模型方法:

class Task < ActiveRecord::Base
  # ...
  def project_name
    project.tasks.length > 0 ? "#{project.name} - #{name}" : project.name
  end
end

如果项目中有一项或多项任务,我们的想法是提供额外的项目信息。

但是,如果在视图上定期调用,则会产生性能问题(特别是对于不断增长的数据集)。

优化此查询的最佳方法是什么,以便在从&#34;每个&#34;中调用时不会创建N + 1个查询类型问题。在视图中循环?

1 个答案:

答案 0 :(得分:2)

结帐Eager Loading in the Rails guide。基本上你使用includes方法一次加载所有任务而不是N + 1方法。

但是对于您的示例,更好的方法是使用counter caching。这预先计算了每个项目引用的任务数。你也打破了关注点的分离/告诉,不要问&#39;通过将project_name逻辑放在Task类中,它应该属于Project类:

class Task
  def project_name
    project.name(self)
  end
end


class Project
  def name(task = nil) 
    return read_attribute[:name] if task.nil?
    tasks_count > 0 ? "#{read_attribute[:name]} - #{task.name}" : read_attribute[:name]
  end
end