我有一个需要很长时间才能呈现的页面。一半的时间(3秒)花费在.find调用上,该调用具有一堆渴望加载的关联。我真正需要的是每种情况下相关记录的数量,以显示在表格中:我不需要实际的记录本身。有没有办法急于加载计数?这是一个简化的例子:
@subjects = Subject.find(:all, :include => [:questions])
在我的表格中,对于每一行(即每个主题),我只显示主题字段的值和每个主题的相关问题的数量。我可以优化上述查找呼叫以满足这些要求吗?
我考虑使用组字段,但我的完整调用包含一些不同的关联,有一些二阶关联,所以我认为group by不会起作用。
@subjects = Subject.find(:all, :include => [{:questions => :tags}, {:quizzes => :tags}], :order => "subjects.name")
:在这种情况下,标签是通过标签的二阶关联。这是我的关联,以防不清楚发生了什么。
Subject
has_many :questions
has_many :quizzes
Question
belongs_to :subject
has_many :taggings
has_many :tags, :through => :taggings
Quiz
belongs_to :subject
has_many :taggings
has_many :tags, :through => :taggings
感谢任何建议 - 最多
答案 0 :(得分:3)
我认为最好在:counter_cache
关联上使用belongs_to
。
class Subject < ActiveRecord::Base
has_many :questions
end
class Question < ActiveRecord::Base
belongs_to :subject, :counter_cache => true
end
要使用counter_cache
,您还需要在questions_count
表格中添加subjects
列。
来自railsapi.com
:
<强>:counter_cache 强>
缓存所属对象的数量 在关联类上通过使用 increment_counter和 decrement_counter。计数器缓存 当一个对象时,它会递增 class是在创建和递减时 它被摧毁了[...]
答案 1 :(得分:1)
您可以为此目的实现计数器缓存。我在Albums模型上维护一个计数器,该模型跟踪与其相关的照片数量。我的过程看起来有点像这样(我相信我在某个博客上发现了这种方法,所以我对原始代码不予理睬):
在照片模型上:
after_save :update_counter_caches
after_destroy :update_counter_caches
def update_counter_caches
self.albums.each { |a| a.update_count } unless self.albums.empty?
end
在相册模型上:
def update_count
update_attribute(:photographs_count, self.photographs.length)
end
相册中您需要的迁移:
class AddCounterCacheColumnToModels < ActiveRecord::Migration
def self.up
add_column :albums, :photographs_count, :integer, :default => 0
end
def self.down
remove_column :albums, :photographs_count
end
end
除非我误解了你的问题,否则这应该是达到你想要的一种非常巧妙的方式。它在我目前的项目中运作良好。 :)
编辑:作为一个注释,我使用此设置而不是默认值:counter_cache方法的原因是因为我需要在一个模型上为多个关联维护多个计数器。据我所知,你无法实现:counter_cache。
答案 2 :(得分:0)
我认为最快的方式:
@subjects = Subject.count(:joins => :questions, :select => 'DISTINCT(questions.id)')
我不确定更复杂的查询(未经测试):
@subjects = Subject.count(:joins => [{:questions => :tags}, {:quizzes => :tags}], :select => 'DISTINCT(tags.id)'