最常用的cache应该是页面的片段缓存
和底层缓存
。
如果要使用片段缓存,则需要在
/config/environments/development.rb
中打开配置:
config.action_controller.perform_caching = true
生产环境默认是打开的。
一般在views
使用,例如:
<% cache ['store', Product.latest] do %>
<% @products.each do |product| %>
<% cache ['entry', product] do %>
<div class="entry">
<%= image_tag(product.image_url) %>
<h3><%= product.title %></h3>
<%= sanitize(product.description) %>
<div class="price_line">
<span class="price"><%= number_to_currency(product.price) %></span>
</div>
</div>
<% end %>
<% end %>
<% end %>
cache
方法表示:如果Product.latest
没有更新,则直接获取缓存中的store
片段,显示在页面中。并且在store
片段中,如果product
也没有更新,也是直接获取缓存中的entry
片段显示在页面中。
一旦Product.latest
有更新,则expires
(过期)store
中的缓存,并且在后端进行查询后,获得Product.latest
,再缓存到store
中去。同理entry
缓存也是一样的原理。
这样就可以对一些更新不频繁的片段页面(比如页面中的本周热度最高的产品列表)进行缓存处理,提高这个片段页面的读取速度,同时一旦片段页面中发生变化,也能及时的更新并将更新后的内容缓存起来。
当然还有很多参数可以设定,也有一些其它方法可以使用。看源码就行了。
- 底层缓存
如果不想缓存视图片段,只想缓存特定的值或者查询结果,则可以用底层缓存
ActiveSupport::Cache::Store
感觉一般使用在models
中,比如:
def random_users
Rails.cache.fetch("random_users", expires_in: 1.day) do
User.order('RAND()').limit(2).to_a
end
end
上面定义了一个方法random_users
,该方法返回一个数组,先随机排序后,再获得前两个user
,并且在1天之内该方法的返回值不会变化。
值得注意的是cache中的查询后面有一个
to_a
方法将查询的结果转换成了数组存在cache中。
这是因为如果不加to_a
,那么cache中存的是一个ActiveRecord::Relation
,而每次需要数据的时候,才会去查询,这样,每次查询出来的结果肯定不一样。所以需要转换成数组,将数据存放在cache中。
参考这个帖子的回复
数据缓存查询
避免N + 1
查询:使用Eager Loading Associations
。可以看这个后记
cache
对我而言是一个复杂的机制,需要不断的理解熟悉。希望以后可以正确并熟练的使用cache
。