Ruby on rails Rails4:模型缓存(低级缓存)

Ruby on rails Rails4:模型缓存(低级缓存),ruby-on-rails,caching,ruby-on-rails-4,activerecord,Ruby On Rails,Caching,Ruby On Rails 4,Activerecord,我正在尝试缓存活动记录查询的结果 以下是我的用例: 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.wher

我正在尝试缓存活动记录查询的结果

以下是我的用例:

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
以下是两个问题:

  • self.awesome\u users\u cached不会缓存结果,最终会访问
  • 所有的超级用户最终都会变成一个数组而不是活动记录,因此我无法从中筛选出更少的超级用户
    有一种解决方案似乎不再适用于Rails4:

    您永远不应该缓存ActiveRecord实例或复杂对象。相反,您应该缓存简单的原语值,例如记录的主键

    就你而言,还有一个问题<代码>其中(awesome:true)返回的是范围,而不是查询结果。因为作用域是延迟执行的,所以您实际上从不缓存任何内容,而是始终执行查询

    如果要缓存查找,请执行繁重查询并返回受影响记录的ID。然后执行第二个查询,按id获取记录。您将运行两个查询,但第一个查询(最昂贵的一个)将在第一次之后缓存

    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)