我有一个类,其中查找实例很昂贵,因此实例被缓存:
class Foo
def self.find(id)
Rails.cache.fetch("Foo.#{id}") do
// some expensive lookup, like an HTTParty request, or a long SQL query
...
end
end
end
在Foo
具有相关Foo
s:
class Foo
def children
@child_foo_ids.map { |id| Foo.find(id) }
end
end
我想使用||=
缓存来保存重复的行程:
class Foo
def children
@children ||= @child_foo_ids.map { |id| Foo.find(id) }
end
end
但是Rails.cache
冻结了找到的Foo
,所以在创建和缓存对象后我无法设置实例变量。 (即此方法引发TypeError
。)
当我第一次执行昂贵的查找时,一种解决方案是预取parent
,但当我只需要一个或两个实例时,最终会加载一个巨大的对象图
答案 0 :(得分:5)
你可以使用||=
缓存;你只需要使用一点间接:
class Foo
def initialize
@related_objects = {}
end
def children
@related_objects[:children] ||= @child_foo_ids.map { |id| Foo.find(id) }
end
end
Rails.cache
不会冻结每个Foo
的实例变量,因此可以修改Hash
!