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

ruby_newbie · 2016年06月12日 · 最后由 xguox 回复于 2016年06月12日 · 2867 次阅读
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 缓存结果而不是代码呢?

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

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

Server.all.order('server_index DESC')

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

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

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

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

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

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