alt
alt

Reputation: 13927

Rails count number of row where column matches ID

So I have a posts model and votes model where the votes are associated to a post by the post_id.

Posts Model

class Post < ActiveRecord::Base
  attr_accessible :comment_count, :downvote, :id, :text, :title, :upvote, :url, :user_id, :users_voted_up_by, :users_voted_down_by

  serialize :users_voted_up_by
  serialize :users_voted_down_by

  belongs_to :user

  has_many :votes
end

Votes Model

class Vote < ActiveRecord::Base
  attr_accessible :direction, :post_id, :type, :voter_id

  belongs_to :user

  belongs_to :post

  belongs_to :comment
end

I need to query the database for all rows in the Votes table that have the current post_id of the post in my loop:

<% @posts.each do |post| %>
    <%= Vote.count(:post_id, params[:post_id]) %>
<% end %>

But that just counts every row, what can i write so that they are associated?

Upvotes: 0

Views: 817

Answers (1)

PinnyM
PinnyM

Reputation: 35531

The recommended approach would be to use a grouping in the query:

<% vote_counts = Vote.group(:post_id).
        where(:post_id => @posts.map(&:id)).count %>
<% @posts.each do |post| %>
  <%= post.id %>: <%= vote_counts[post.id] || 0 %>
<% end %>

The advantage to the grouped query is that it only hits the database once. If you prefer to get a single count for each post for some unfathomable reason you can simply use:

<% @posts.each do |post| %>
  <%= post.id: %> <%= post.votes.count %>
<% end %>

Don't let the simplicity of the second method fool you, though. It's asking for trouble as it involves an N+1 pattern.

Upvotes: 3

Related Questions