【问题标题】:Rails 3 - Queries with sub models and count statementsRails 3 - 带有子模型和计数语句的查询
【发布时间】:2011-01-20 19:10:00
【问题描述】:

我正试图找出一种方法来消除一堆看似不必要的查询。情况如下。

模型帖子有_很多评论

SQL (0.1ms) SELECT COUNT(*) FROM "cmets" WHERE ("cmets".post_id = 5)
缓存(0.0ms)从“cmets”WHERE(“cmets”.post_id = 5)中选择计数(*)
缓存(0.0ms)从“cmets”WHERE(“cmets”.post_id = 5)中选择计数(*)
CACHE (0.0ms) SELECT COUNT(*) FROM "cmets" WHERE ("cmets".post_id = 5)

所以我不确定为什么这些正在运行,但在我看来,我正在检查每个帖子是否有 cmets

<% 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 是否适合我。

欢迎提出建议

【问题讨论】:

    标签: ruby-on-rails-3


    【解决方案1】:

    这里的问题是你可能不是eagerly loading comments 每个帖子。无论您在控制器中的哪个位置设置 post 变量,您都可能会遇到这样的情况:

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

    尝试将其更改为:

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

    Includes 将自动更改您的 Post load 查询以加入 cmets 并使用该帖子的所有 cmets 的数组预填充 post.comments。然后当您执行post.comments.size 时,您将询问数组的长度(而不是询问 activerecord 来计算有多少)。

    【讨论】:

    • 我正在运行我的查询...@posts = @current_account.posts.all(:include => [:cmets]).all,但不确定这是最好的方法做。 (尤其是 Rails 3.1
    【解决方案2】:

    嗯...#includes是类方法,不能在Post.find(params[:id])返回的实例上调用它,原则上是正确的,语法是Post.includes(:comments).find(params[:id])

    回应您的评论:

    好的,#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,但看看哪个更适合你。

    【讨论】:

    • 我正在运行我的查询...@posts = @current_account.posts.all(:include => [:cmets]).all,但不确定这是最好的方法做。 (尤其是 Rails 3.1
    • 根据您的评论编辑了答案。看看有没有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 2021-05-15
    相关资源
    最近更新 更多