我使用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" = $1 LIMIT $2 [["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
我希望&#34; distance = Distance.new({:distance =&gt; my_obj.distance,:distance_unit =&gt; my_obj.distance_unit})&#34;用于调用我的缓存功能而不是运行到数据库的行。我怎样才能做到这一点?
答案 0 :(得分:0)
关于我的评论,请注意memory_store仅在进程中使用,因此每个进程都有自己的存储(如果这是一个问题,请考虑MemCacheStore
)。当进程结束时,缓存也消失了。
作为一般说明:如果尚未提取对象,则belongs_to
关联本身会触发查找 。 Rails框架中内置了大量缓存,一般来说,我不会过早担心过早优化(只有在发现查询运行速度太慢时才会优化)。
另外:访问缓存也是对一种数据库的调用,基于可能索引的id的查找通常不是一个沉重的调用。如果只有几个距离单位,你可能只是使用一个常量可以工作吗?
但要回答你的问题。您的代码中似乎没有任何内容表示cached_find_by_id
(虽然rails自动执行了很多操作,但这不是其中之一)。
您可以在MyObject
中创建以下方法,以覆盖“getter”&#39;由belongs_to
关联创建:
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})