0

在待办事项列表式的应用程序,我有以下的ActiveRecord的模型方法:如何避免Rails的“每个”循环中的N + 1查询?

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

的想法是提供更多的项目信息,如果有该项目的一个或多个任务。但是,当在视图上定期调用时,会产生性能问题(特别是在数据集不断增加的情况下)。

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

回答

2

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

但是对于您的示例,更好的方法是使用counter caching。这将预先计算每个项目引用的任务数量。你还打破了关注点分离/“讲,不问”一点通过将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