我正在尝试缓存Active Record Query的结果。
这是我的用例:
User.rb
def self.awesome_users_cached
Rails.cache.fetch("awesome_users") { where(awesome: true) }
end
UsersController
def index
all_awesome_users = User.awesome_users_cached
less_awesome_users = User.where(less_awesome_user:true).pluck(:id)
@users = all_awesome_users.where.not(id: less_awesome_users)
end
以下是2个问题:
有一个解决方案似乎不再适用于Rails4:Rails cache with where clause
答案 0 :(得分:3)
您永远不应该缓存ActiveRecord实例或复杂对象。相反,您应该缓存简单的原始值,例如记录的主键。
在您的情况下,还有一个问题。 where(awesome: true)
返回范围,而不是查询结果。因为范围是惰性执行的,所以除了始终执行查询之外,您实际上从不缓存任何内容。
如果要缓存查找,请执行繁重查询并返回受影响记录的ID。然后执行第二个查询,通过id获取记录。您将运行2个查询,但第一个查询(最昂贵的查询)将在第一次之后缓存。
def self.awesome_users_cached
ids = Rails.cache.fetch("awesome_users") { where(awesome: true).pluck(:id) }
find(ids)
end
您可以缓存第一个查询的查找,但正如我之前提到的,这不是一个好主意。
def self.awesome_users_cached
Rails.cache.fetch("awesome_users") { where(awesome: true).to_a }
end
您还可以使用其他查询方法,以便您可以轻松地将其他条件链接到缓存查询。
def self.awesome_users_cached
ids = Rails.cache.fetch("awesome_users") { where(awesome: true).pluck(:id) }
where(id: ids)
end
awesome_users_cached.where.not(id: same_company_users)