2

我有一个控制器方法,目前看起来像:

@people = Person.where(conditions).includes(eager_fetch).all

我现在正试图让控制器缓存感知。由于 Eager fetch 相当昂贵,因此我想避免加载尽可能多的数据。如果相关,则输出是来自 RPC 样式端点的 XML。我已经到达:

@people = Person.where(conditions).all
@fragments = {}
@people.dup.each do |person|
  cache_key = "fragment-for-#{person.id}-#{person.updated_at.to_i}"
  fragment = Rails.cache.fetch(cache_key)
  unless fragment.nil?
    @fragments[person.id] = fragment
    @people.delete person
  end
end
@people = Person.where(:id => @people.collect(&:id)).includes(eager_fetch).all

还有另一种可能性,非常相似,只是不是在最后一行重新查询,

Person.send :preload_associations, @people, eager_fetch

我是否缺少正确处理此问题的重要 API?目前在 Rails 3.0.12 上,但将升级到 3.2.x,所以只适用于 3.2.x 的解决方案就可以了。我的解决方案对我来说都不优雅。

(我已经匿名化并简化了这段代码,如果我遗漏了任何重要的东西,我深表歉意)

4

1 回答 1

0

不要依赖 ActiveRecord 的急切加载。它将加载不在 ActiveRecord 每个请求查询缓存中的所有内容。

而是查询您的主要对象,然后使用您自己的狡猾方法来获取缓存的内容并查询较慢的数据存储以查找丢失的 ID。

于 2012-09-27T05:35:47.413 回答