dimanche 14 février 2016

Rails 3.2 way to count conditional associations without 1+n queries

Consider the following models:

User < ActiveRecord::Base
  has_many :posts
end

Post < ActiveRecord::Base
  belongs_to :user
end

Now I wish to display the Users with their number of posts in the last 24 hours.

Obviously a counter_cache would not work here, since I only want to count the records matching the condition created_at > 24.hours.ago

In the controller I would have this:

@users = User.order(:name)

In the view I would have this

<table>
  <tr>
    <th>Name</th>
    <th>Recent posts</th>
  </tr>
  <% @users.each do |user| %>
  <tr>
    <td><%= user.name %></td>
    <td><%= user.posts.where('created_at > ?', 24.hours.ago).count %></td>
  </tr>
  <% end %>
</table>

Now this obviously makes a query for every User, causing the dreaded 1+n query problem. Since the count is conditional, adding .includes(:posts) in the controller has no effect.

Getting the results in raw SQL would be trivial. What would be the correct Rails way to get these results? Preferably in a way to also works in the older 3.2 version.

Aucun commentaire:

Enregistrer un commentaire