该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-10-06
可以参考一下CachedModel的代码:
1、User.find(1, :select => "id,name") 这个问题CachedModel解决的挺好,他直接拦截find_by_sql方法,插入缓存。另外CachedModel对于非 find :all的查询语句,会自动把得到的结果集遍历model对象,把每个model对象插入缓存,自动的把查询缓存转化为对象缓存,我觉得这个思路挺好。 2、还要考虑Transaction回滚的问题 如果Transaction回滚,那么cache已经被更新了,就会出现Cache和数据库数据不一致的现象。所以CachedModel对ActiveRecord的transction方法也做了改写,把更新缓存的动作延迟到事务成功提交之后才执行。 |
|
返回顶楼 | |
发表时间:2008-10-09
2. 对于belongs_to/has_one等关系的一方,如果该model被标记为使用cache,调用关系方法的时候也将会先从cache中查找。
我在用插件的过程中发现 如果user has_many image 对user缓存没问题,但好像无法对image进行缓存。 像user.images这样来访问的话 第一次直接读数据库没问题,但如果后面从缓存中取数据的话,会报:undefined method `images' 是不是我哪里出了问题. |
|
返回顶楼 | |
发表时间:2008-10-09
这个插件对于many的集合是没有做缓存的,调用user.images都是从数据库查询的,你说的从缓存取是自己写的代码吧?把代码贴上来看看。
|
|
返回顶楼 | |
发表时间:2008-10-09
没有自己写缓存,用的是你的插件。
Model user里面代码如下: acts_as_cached def self.get_users get_cache("users") {find(:all)} end Action里面代码如下: def users @users = User.get_users respond_to do |format| format.html # index.html.erb format.xml { render :xml => @users } end end 在view里面这样访问: <% for user in @users %> <% if user.images.size > 0 -%> .... <% end -%> <% end %> 第一次访问从数据库读取数据没任何问题,但当再次访问的时候就报错。 |
|
返回顶楼 | |
发表时间:2008-10-09
我试了一下,不会报错
class User < ActiveRecord::Base acts_as_cached has_many :images def get_users get_cache("users") {find :all} end end ruby script/console >> User.get_users #cache miss >> users = User.get_users #cache hit >> users[0].images.size #正确输出 你检查后台log看看,是不是其他错误造成的? |
|
返回顶楼 | |
发表时间:2008-10-09
有点奇怪,我在console下测试也没问题,但是在view里面执行,就是报错!
|
|
返回顶楼 | |
发表时间:2008-10-09
在Action里面对@users遍历访问iamges,同样的问题。报undefined method `images',但在console下测试没有问题
def users @users = User.get_users @users.each { |i| i.images.size} respond_to do |format| format.html # index.html.erb format.xml { render :xml => @users } end end |
|
返回顶楼 | |
发表时间:2008-10-09
可能和我前面文章中讲的第4点有关系:
4. memcached的undefined class/module错误,从cache_fu抄袭了一个autoload_missing_constants方法来解决这个问题: http://www.philsergi.com/2007/06/rails-memcached-undefinded-classmodule.html 你试试看在action的第一行写一下Image,让rails先load这个class,看看还会不会出错。 我明天再写代码调试看看到底是什么原因。 ---分割线--- 后来我在view和action里面都实验了,还是无法重现你说的错误,是不是你在开发环境没有用mem_store? Rails默认使用MemoryStore作为cache,在开发环境下是会和class reload有冲突: http://rails.lighthouseapp.com/projects/8994/tickets/785-caching-models-fails-in-development |
|
返回顶楼 | |
发表时间:2008-10-10
测试了一下,是默认的MemoryStore会和class reload有冲突,造成这个问题。
具体的原因可以看上面的链接。 只要指定config.cache_store = :mem_cache_store使用MemcacheStore就可以了。 |
|
返回顶楼 | |
发表时间:2008-10-21
Good Job
可以讓我學學Cache的一些技巧 剛好項目會用上呢0ˇ0 |
|
返回顶楼 | |