我如何强制 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})
我正在使用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})