使用Rails.cache.fetch混淆缓存Active Record查询 [英] Confusion caching Active Record queries with Rails.cache.fetch
问题描述
我的版本是:
- 路轨:3.2.6
- 达利:2.1.0
我的环境是:
- config .action_controller.perform_caching = true
- config.cache_store =:dalli_store,'localhost:11211',{:namespace =>'MyNameSpace'}
我写的时候:
Rails.cache.fetch(key) do
User.where('status = 1').limit(1000)
end
无法缓存用户模型。如果我使用
The user model can't be cached. If I use
Rails.cache.fetch(key) do
User.all
end
它可以被缓存。如何缓存查询结果?
it can be cached. How to cache query result?
推荐答案
原因是因为
User.where('status = 1').limit(1000)
返回一个 ActiveRecord :: Relation
实际上是一个范围,而不是一个查询。 Rails缓存作用域。
returns an ActiveRecord::Relation
which is actually a scope, not a query. Rails caches the scope.
如果要缓存查询,则需要在最后使用查询方法,例如 #all
。
If you want to cache the query, you need to use a query method at the end, such as #all
.
Rails.cache.fetch(key) do
User.where('status = 1').limit(1000).all
end
请注意缓存ActiveRecord对象绝不是一个好主意。缓存对象可能导致状态和值不一致。如果适用,应始终缓存原始对象。在这种情况下,请考虑缓存ID。
Please note that it's never a good idea to cache ActiveRecord objects. Caching an object may result in inconsistent states and values. You should always cache primitive objects, when applicable. In this case, consider to cache the ids.
ids = Rails.cache.fetch(key) do
User.where('status = 1').limit(1000).pluck(:id)
end
User.find(ids)
您可能会争辩说,在这种情况下,始终执行对 User.find
的调用。没错,但是使用主键的查询速度很快,并且可以解决我之前描述的问题。此外,缓存活动记录对象可能会很昂贵,并且您可能很快就会只用一个缓存条目来填充所有Memcached内存。缓存ID也会防止此问题。
You may argue that in this case a call to User.find
it's always executed. It's true, but the query using primary key is fast and you get around the problem I described before. Moreover, caching active record objects can be expensive and you might quickly end up filling all Memcached memory with just one single cache entry. Caching ids will prevent this problem as well.
这篇关于使用Rails.cache.fetch混淆缓存Active Record查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!