2011-01-20 36 views
1

我想弄清楚一种方法来消除一堆似乎不必要的查询。这是情况。Rails 3 - 查询子模型和计数语句

模型后的has_many评论

SQL(0.1毫秒)SELECT COUNT(*)FROM “意见” WHERE( “意见” .post_id = 5)
CACHE(0.0ms)SELECT COUNT(*)FROM“ (*)FROM“comments”WHERE(“comments”.post_id = 5)
CACHE(0.0ms)SELECT COUNT(*) FROM“comments”where(“comments”.post_id = 5)

所以我不知道为什么这些都在运行,但在我看来,我正在检查,看看是否re对每个帖子发表评论

<% if post.comments.count > 0 %> <!-- tried count, size, blank? --> 
    <table class="list"> 
    <% post.comments.each do |animal| %> 
     <tr><!-- stuff here --></tr> 
    <% end %> 
    </table> 
<% else %> 
    <h3>No comments</h3> 
<% end %> 

如果有更好的方法来做这个检查我都是为了改变。我看着counter_cache,但看起来只是为belongs_to关系,我也使用子域名,所以不知道counter_cache是​​否适用于我。

任何建议,欢迎

回答

1

这里的问题是,你可能不会eagerly loading comments每个岗位。无论你是设置在控制器中的变量后,你可能有这样的事情:

post = Post.find(params[:id]) 

尝试将其更改为这样:

post = Post.includes(:comments).find(params[:id]) 

包括会自动改变你的帖子负荷查询,以便对意见并预先填充post.comments与所有帖子的评论数组。然后当你做post.comments.size时,你会问数组的长度(而不是询问activerecord来计算有多少)。

+0

我正在运行我的查询...... @posts = @ current_account.posts.all(:include => [:comments])。所有,但不确定这是做到这一点的最佳方式。 (特别是对于Rails 3.1 – bokor 2011-01-21 05:05:28

0

嗯...#包括是一个类的方法,你不能把它由Post.find(params[:id])返回的情况下这是原则上是正确的,但是,语法是Post.includes(:comments).find(params[:id])

在回答您的评论:

OK,#includes是ActiveRecord :: Base及其子代(您的模型)的类方法,但是是ActiveRelation的实例方法。

@posts = @current_user.posts.all(:include => [:comments]).all 

肯定是过时......你想你调用的Rails 3 #ALL B/C之前做的包容,@current_user.posts将返回一个ActiveRelation对象,而@ current_user.posts.all是要实际负载Post对象的集合。所以我会改变它:

@posts = @current_user.posts.includes(:comments).all 

你甚至不需要打电话#all,说实话,但看看哪个更适合你。

+0

我正在运行我的查询...... @posts = @ current_account.posts.all(:include => [:comments])。所有,但不确定这是做到这一点的最佳方式。(特别是对于Rails 3.1 – bokor 2011-01-21 05:06:45