新手问题 Rails.cache 缓存似乎把代码缓存了,而不是把结果缓存了

ruby_newbie · 发布于 2016年06月12日 · 最后由 xguox 回复于 2016年06月12日 · 1219 次阅读
24609
class Server < ActiveRecord::Base

  belongs_to :user

  class << self
    def fetch_server_list
      Rails.cache.fetch("server_list", expires_in: 3.hours) do
        Rails.logger.debug("-----------------> query all servers")
        Server.all.order('server_index DESC')
      end
    end
  end

end

第一次调用 fetch_server_list 的时候,有 "-----------------> query all servers" 第二次调用 fetch_server_list 的时候,就没有这个日志 说明缓存生效了

但是问题来了 每次调用都会执行SQL语句

怎样才能让cache缓存结果而不是代码呢?

共收到 8 条回复
15999

缓存的是块里面程序的最终执行结果,如果你块里面的程序执行完输出的是sql语句,比如ActiveRecord::Relation,(User.all), 那下次访问得到数据也是要执行该sql. 如果块里面的程序执行完输出的是数据如(User.all.to_a), 那下次就不用执行查询了。

24609

#1楼 @embbnux 谢谢了!确实有效果

718
Server.all.order('server_index DESC')

返回的是一个ActiveRecord_Relation实例,这东西不是一堆Server的对象,当你读取ActiveRecord_Relation的数据的时候,才真正的去查询数据库,所以看起来没次都是去执行了SQL的。 你可以把查询结果变成纯粹的ruby hash再缓存

Server.all.order('server_index DESC').map(&:attributes)
24609

#3楼 @ch3n 谢谢,这个方法看上去也不错

65eef6

之前遇到过这个疑问,
楼主如果是真的要缓存所有的查询结果的话还得慎重哦, 不然把整个结果集塞进内存有可能要爆呢, 如果是 MemoryStore 的话

24609

#5楼 @xguox 赞,feed了

8

#5楼 @xguox 哇,高产!

65eef6

#7楼 @hooopo 被发现了 (逃 = . =

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册