【发布时间】:2012-02-25 21:33:36
【问题描述】:
我正在尝试缓存 ActiveRecord 及其关联。 问题是在访问检索到的记录上的关联时存在数据库查询。
通常情况下,我会使用即时加载 Rails.cache.write('post', Post.includes(:comments).find(99)) 进行缓存。这似乎可行,但问题是我只想缓存关联的有限子集,并且在急切加载时会忽略限制(例如提到here)。所以Post.includes(:popular_comments).find(99) 将返回所有 cmets,而不仅仅是流行的。
所以我尝试在延迟加载关联后缓存对象,但不幸的是在拉出对象时会出现查询:
class Post < ActiveRecord::Base
has_many :comments
has_many :popular_comments, :class_name > 'Comment', :limit => 20, :order => :votes
post = Post.find(99)
post.popular_comments # lazy-load limited associations
Rails.cache.write('post', post)
...
Rails.cache.read('post').popular_comments # Unwanted SQL query :(
我已经尝试缓存一个克隆,同样不需要的 SQL 查询。我已经尝试过 redis 和 memcached 实现,结果相同。奇怪的是,这个序列确实可以在控制台上运行,但是在控制器或视图中的简单用法会失败(即发生 SQL)。
更新(2017 年 4 月):我现在想说这是一个愚蠢的前提。缓存整个对象通常是浪费的,因为它使用大量缓存存储并且序列化/反序列化它们很慢。缓存关联(如在这个问题中所问的)也将浪费乘以 N。通常只缓存原始 ID 和 HTML 片段会更有效。
【问题讨论】:
-
你运行的是哪个版本的 Rails?
-
@Brandan 这是在 Rails 3.1 上
-
您能否发布日志的 sn-p 以准确显示正在执行的 SQL 以及它在请求中发生的位置?我无法重现这个。
-
@Brandan 现在没有这个确切的代码,但我会看看我是否可以用一个虚拟项目来重现它。
-
您的 Rails 版本是什么?我在我的设置中尝试了这个,它对我有用。
标签: ruby-on-rails ruby-on-rails-3 caching activerecord