Ruby on rails 写ActiveRecord是否有许多扩展重新查询数据库?

Ruby on rails 写ActiveRecord是否有许多扩展重新查询数据库?,ruby-on-rails,optimization,activerecord,Ruby On Rails,Optimization,Activerecord,如果我有这样的东西: class Post < ActiveRecord::Base has_many :comments, :as => :commentable do def approved find(:all, :conditions => {:approved => true}) end end end class Comment < ActiveRecord::Base belongs_to :commentab

如果我有这样的东西:

class Post < ActiveRecord::Base
  has_many :comments, :as => :commentable do
    def approved
      find(:all, :conditions => {:approved => true})
    end
  end
end

class Comment < ActiveRecord::Base
  belongs_to :commentable, :polymorphic => true
end

看起来它应该只过滤内存中当前的注释数组,不是吗?是这样吗?我询问的原因是,尽管我已经调用了
post.comments
,但控制台在
post.comments.approved
上显示了
SELECT*FROM…
。是否应该在ActiveRecord中对此进行更好的优化?

这是可选的,因为在某些情况下,您可能只希望在需要时加载关联的对象。如果希望将它们全部加载到内存中,则需要使用:include标志显式声明希望包含在初始查询中的对象。例如:

post = Post.find(:first, :include => :comment)

您可能需要重写扩展以利用该功能。。。一种方法是将“approved”函数更改为迭代每个帖子附带的评论数组,并返回一个新数组,其中过滤掉未经批准的评论。您明确定义的“find”返回数据库。

AR对关联扩展方法内的任何finder调用执行新的查询。 您可以使用
self
引用缓存的结果集

  has_many :comments, :as => :commentable do
    def approved
      # uses the cached result set
      self.select{|c| c.approved == true}
    end
  end

如果您的查询真的那么简单,那么您需要的是一个命名范围:

class Comment
  named_scope :approved, :conditions => {:approved => true}
end
然后,您可以执行以下操作:

@post.comments.approved.count #=> 1 DB hit!
@post.comments.count #=> Another DB hit - can't reuse same scope
看看(Rails 2.3中的命名范围)

@post.comments.approved.count #=> 1 DB hit!
@post.comments.count #=> Another DB hit - can't reuse same scope