代码之家  ›  专栏  ›  技术社区  ›  Patrick Klingemann

Rails 3 ActiveRecord查询,返回模型的所有记录,并在单个查询中包含关联记录的计数

  •  1
  • Patrick Klingemann  · 技术社区  · 15 年前

    我有以下型号:

    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>
    

    1 回复  |  直到 15 年前
        1
  •  3
  •   Ariejan    15 年前

    您可以使用计数器缓存。这将在父对象上保留一个带有子对象数的整数值。动态记录保持跟踪。

    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 = ?