【问题标题】:Rails 3 ActiveRecord Query, return all records of a model and include a count of associated records in a single queryRails 3 ActiveRecord 查询,返回模型的所有记录并在单个查询中包含关联记录的计数
【发布时间】:2010-11-02 12:10:18
【问题描述】:

我有以下型号:

class Keyword < ActiveRecord::Base
  has_many :tags
  has_many :studies, :through => :tags
end

class Tag < ActiveRecord::Base
  belongs_to :keyword
  belongs_to :study
end

class Study < ActiveRecord::Base
  has_many :tags
  has_many :keywords, :through => :tags
end

我想要一个包含所有关键字的数组,对于每个关键字,以及用该关键字标记的研究计数,这样我就可以说:

<ul>
<% @keywords.each do |keyword| %>
  <li><%= "(#{keyword.number_of_studies}) #{keyword.title}") %></li>
<% end %>
</ul>

我确定这是可能的,问题是:如何?

【问题讨论】:

    标签: ruby-on-rails activerecord ruby-on-rails-3 arel


    【解决方案1】:

    您可以使用计数器缓存。这会在父对象上保留一个整数值,其中包含子对象的数量。 ActiveRecord 保持跟踪。

    class Post < AR::Base
      has_many :comments
    end
    
    class Comment < AR::Base
      belongs_to :post, :counter_cache => true
    end
    
    @post.comments_count
    

    如果你真的必须使用一个没有计数器缓存的查询:

    @post = Post.find(first, :select => 'posts.*, count(comments.id) as comments_count',:joins => 'left outer join comments on comments.post_id = posts.id', :group => 'posts.id')
    @post.comments_count #=> From join query.
    

    如您所见,这很快就会变得丑陋。最好坚持使用计数器缓存,或者执行两个单独的查询。

    @post = Post.find(:first) # SELECT FROM posts
    @post.comments.count      # SELECT COUNT(1) FROM comments WHERE post_id = ?
    

    【讨论】:

    • 好的,这绝对解决了问题。我希望进行某种 ARel 查询,尽管当我获得所有关键字时,这会给我作为查询的一部分的计数。我给了你一票。
    • 好的,我已经用你想要的更新了我的答案。我仍然认为您应该使用counter_cache 或执行两个查询。它使您的代码更干净,更不容易出错。
    • 感谢您的详尽回答,我可以从您所拥有的内容中推断出 Rails 3 ARel 查询语法,而您所拥有的正是我想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    • 2011-07-16
    • 1970-01-01
    相关资源
    最近更新 更多