Miniprofiler indicates that my Rails app is making a large number of database queries on every page. The issue seems to be a leaderboard module that is included in the layout.
The application looks like this:
# application_controller.rb
before_filter :initialize_leaderboard
def initialize_leaderboard
@leaderboard_users ||= User.monthly_leaderboard
end
# user.rb
def self.monthly_leaderboard
User.includes(:events).sort_by(&:events_last_month).reverse
end
def events_last_month
@events_last_month ||= events.where( created_at: Date.today.beginning_of_month-1.month..Date.today.end_of_month-1.month ).size
end
# application.html.erb
...
<% unless @leaderboard_users.blank? %>
<% cache ["sidebar_leaderboard", @leaderboard_users] do %>
...html
<% end %>
<% end %>
In the logs and miniprofiler output, I am seeing an events_last_month query for every user. This is less than desirable, and is making me question my understanding of how this all works. Have I go this right?
- The view is cached, so provided that a particular leaderboard_user has been viewed before (recently), his details should be displayed from the cache.
- So the many
events_last_monthqueries must be originating from theinitialize_leaderboardmethod in application_controller.rb. But, I understood that using||=would cache the response of theUser.monthly_leaderboardmethod for subsequent requests. Why is it being called on each page view?