【发布时间】:2012-09-24 23:41:19
【问题描述】:
我在控制器中设置了这两个变量。我如何缓存这些,这样它们就不会每次都与数据库通信,只有第一次。
@tablenutrients = Nutrient.find(:all)
@columnnutrients = @tablenutrients.collect {|x| x.nutrient}
【问题讨论】:
标签: ruby-on-rails ruby caching activerecord memcached
我在控制器中设置了这两个变量。我如何缓存这些,这样它们就不会每次都与数据库通信,只有第一次。
@tablenutrients = Nutrient.find(:all)
@columnnutrients = @tablenutrients.collect {|x| x.nutrient}
【问题讨论】:
标签: ruby-on-rails ruby caching activerecord memcached
@djlumley 说了什么。
一般来说,您还可以配置和使用ActiveSupport::Cache::Store 来显式存储您自己的自定义变量。然后,您可以获取/设置缓存值,例如,如下所示:
@tablenutrients = Rails.cache.fetch("tablenutrients") do
Nutrient.find(:all)
end
【讨论】:
如果您的数据库设置正确,它应该默认缓存您的数据。如果您使用的是 MySQL 或 postgresql,您可以更改缓存使用的 RAM 数量,以确保获得较高的缓存命中率。
除了简单的数据库缓存之外,使用 Dalli 之类的东西连接到 memcached 应该可以相当容易地提高性能。
如果设置正确,Rails 应该利用 memcached 将所有活动记录查询缓存在 memcached 中。 Rails guide on caching 和 Dalli documentation 应该可以根据您运行的 Rails 版本帮助您入门。
【讨论】:
Rails 为您提供了一些内置缓存选项,其中两个可能适合您,具体取决于您对查询结果所做的操作:
片段缓存
如果您将其用作选择框的集合,这是一种常用的表单,我会选择此选项。这将使您不仅可以缓存数据库结果,还可以缓存页面的实际 HTML 部分。只需在该部分周围添加<%= cache do %> 即可完成,如下所示:
<html>
...
<body>
...
<div class='content'>
...
<%= cache do %>
<%= select "nutrient", "nutrient", Nutrient.all.collect(&:nutrient) } %>
<% end %>
Rail.cache
您还可以编写一个直接与内置缓存存储对话的方法,方法是在您的 ApplicationController 中放置一个方法,然后让它在 before_filter 回调上运行,例如所以:
application_controller.rb
class ApplicationController < ActionController::Base
before_filter :retrieve_nutrients
def retrieve_nutrients
@nutrients = Rails.cache.fetch("nutrients") do
Nutrient.all.collect(&:nutrient)
end
end
end
在生产环境中的这两种情况下,您都需要设置 Memcached 或 Redis 作为缓存层(它们位于 Rails.cache 后面,易于实现)。我会结帐Rails Guides 以更深入地了解它。
【讨论】: