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