Miniprofiler指示我的Rails应用程序在每个页面上进行大量数据库查询。问题似乎是布局中包含的页首横幅模块。
该应用程序如下所示:
#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 %>
Run Code Online (Sandbox Code Playgroud)
在日志和miniprofiler输出中,我看到了events_last_month每个用户的查询。这不是所希望的,并且让我质疑我对所有这些工作原理的理解。我可以这样吗?
events_last_month查询必须源自initialize_leaderboardapplication_controller.rb中的
方法。但是,我知道使用||=会User.monthly_leaderboard为后续请求缓存方法的响应
。为什么在每个页面视图中都调用它?||=将记住来自的非虚假结果User.monthly_leaderboard。该数据将在ApplicationController实例的生命周期内保留。为每个请求创建一个新实例。
当您的应用程序接收到请求时,路由将确定要运行的控制器和动作,然后Rails创建该控制器的实例,并以与动作相同的名称运行该方法。
如果您希望在请求之间缓存(有时过期并重新查询)该实例变量的值,则需要显式利用外部缓存或寻找另一个位置来存储在请求(例如会话)中持久存在的值(如果结果是)相对较小,并且特定于用户会话。
如果该值应该被查询一次并一直保持到重新启动Web服务器,则可以考虑在初始化程序中查询该数据,并将结果存储在该过程的整个生命周期中都将持续存在的位置。
| 归档时间: |
|
| 查看次数: |
2809 次 |
| 最近记录: |