我如何强制 Rails 使用我的缓存而不是总是去数据库?

How do I force Rails to use my cache instead of always going to the database?

我正在使用Rails 5.我有这个型号

class MyObject < ActiveRecord::Base
    ...
  belongs_to :distance_unit

当我有如下一行时,我注意到了

distance = Distance.new({:distance => my_obj.distance, :distance_unit => my_obj.distance_unit})

它会导致执行以下内容

SELECT  "distance_units".* FROM "distance_units" WHERE "distance_units"."id" =  LIMIT   [["id", 1], ["LIMIT", 1]]

没有异常,但我在 DistanceUnit 模型中创建了一个缓存方法

class DistanceUnit < ActiveRecord::Base

  def self.cached_find_by_id(id)
    Rails.cache.fetch("distanceunit-#{id}") do
      puts "looking for id: #{id}"
      find_by_id(id)
    end
  end

并且我希望 "distance = Distance.new({:distance => my_obj.distance, :distance_unit => my_obj.distance_unit})" 行调用我的缓存功能而不是 运行 关闭到数据库。我怎样才能做到这一点?

关于我的评论,请注意 memory_store 仅在一个进程中使用,因此每个进程都有自己的存储(如果这是一个问题,请考虑 MemCacheStore)。当进程结束时缓存也消失了。

作为一般注意事项:belongs_to 关联固有地触发查找如果尚未获取对象。 Rails 框架中内置了大量缓存,一般来说,我不会太担心一开始的过早优化(只有当您发现查询 运行 太慢时才进行优化)。

此外:访问缓存也是对一种数据库的调用,基于可能索引的 id 的查找通常并不是真正的重调用。另外,如果只有几个距离单位,您也许可以简单地使用一个常量?

但是要回答你的问题。您的代码中似乎没有任何内容表明 cached_find_by_id(虽然 rails 自动执行了很多操作,但这不是其中之一)。

您可以在 MyObject 中创建以下方法来覆盖 belongs_to 关联创建的 'getter':

def distance_unit
  DistanceUnit.cached_find_by_id(distance_unit_id)
end

但是,如果您只是简单地初始化一个 ActiveRecord 对象并且您在此调用中不需要 DistanceUnit,您也可以直接传递 id,因为这就是存储在数据库中。

Distance.new({:distance => my_obj.distance, :distance_unit_id => my_obj.distance_unit_id})