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