【问题标题】:Rails4 : Model caching (low level caching)Rails4:模型缓存(低级缓存)
【发布时间】:2015-05-25 19:00:45
【问题描述】:

我正在尝试缓存 Active Record 查询的结果。

这是我的用例:

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

这里有两个问题:

  1. self.awesome_users_cached 不缓存结果并最终命中
  2. all_awesome_users 最终成为一个数组而不是活动记录,因此我无法从中过滤掉less_awesome_users。

有一个解决方案似乎不再适用于 Rails4:Rails cache with where clause

【问题讨论】:

    标签: ruby-on-rails caching ruby-on-rails-4 activerecord


    【解决方案1】:

    您不应该缓存 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)
    

    【讨论】:

      猜你喜欢
      • 2018-04-04
      • 2011-02-24
      • 2016-08-09
      • 2011-09-26
      • 2016-07-20
      • 2017-11-07
      • 2016-07-20
      • 2015-08-19
      • 2018-04-08
      相关资源
      最近更新 更多