Rails 请问 Rails 3.2.11 中 fresh_when 的用法

wuwx · 发布于 2013年01月10日 · 最后由 huacnlee 回复于 2014年05月30日 · 2583 次阅读
2963

按照huacnlee的BLOG上的用法,以及官方guides的用法,加了一行代码:

def index
  @topics = Topic.includes(:user).page(params[:page]).reverse_order
  fresh_when(:etag => [@topics])
  respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @topics }
  end
end

然后很happy地等待浏览器304相应,可是刷新来刷新去,发现每次ETag值都是变化的 每次请求都是200响应,一点都看不出来有被Cache了,这个是为什么呢

共收到 19 条回复
De6df3

fresh_when 你覆盖过么?

2963

#1楼 @huacnlee 木有覆盖哇,没有重写过这个方法…… 不过发现一个问题,如果是单个对象就可以返回304,列表就不行

De6df3

#2楼 @wuwx 你先打印 Log 出来看看,会不会是列表的数据每次都不同

2963

#1楼 @huacnlee log 来了

Started GET "/topics" for 127.0.0.1 at 2013-01-11 15:07:51 +0800
Processing by TopicsController#index as HTML
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
  Rendered topics/_form.html.erb (3.7ms)
  Topic Load (0.1ms)  SELECT "topics".* FROM "topics" ORDER BY "topics"."id" DESC LIMIT 30 OFFSET 0
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN (1)
   (0.1ms)  SELECT COUNT(*) FROM "comments" WHERE "comments"."topic_id" = 1
   (0.1ms)  SELECT COUNT(*) FROM "flowers" WHERE "flowers"."topic_id" = 1
  Rendered topics/_topic.html.erb (4.3ms)
  Rendered topics/index.html.erb within layouts/topics (11.9ms)
  User Load (0.2ms)  SELECT "users".* FROM "users" LIMIT 10
  Rendered users/_user.html.erb (1.0ms)
  Rendered layouts/application.html.erb (3.7ms)
Completed 200 OK in 22ms (Views: 19.8ms | ActiveRecord: 1.0ms)


Started GET "/assets/application.css" for 127.0.0.1 at 2013-01-11 15:07:51 +0800
Served asset /application.css - 304 Not Modified (4ms)


Started GET "/assets/application.js" for 127.0.0.1 at 2013-01-11 15:07:51 +0800
Served asset /application.js - 304 Not Modified (2ms)


Started GET "/topics" for 127.0.0.1 at 2013-01-11 15:07:52 +0800
Processing by TopicsController#index as HTML
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
  Rendered topics/_form.html.erb (3.8ms)
  Topic Load (0.2ms)  SELECT "topics".* FROM "topics" ORDER BY "topics"."id" DESC LIMIT 30 OFFSET 0
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN (1)
   (0.1ms)  SELECT COUNT(*) FROM "comments" WHERE "comments"."topic_id" = 1
   (0.1ms)  SELECT COUNT(*) FROM "flowers" WHERE "flowers"."topic_id" = 1
  Rendered topics/_topic.html.erb (4.5ms)
  Rendered topics/index.html.erb within layouts/topics (12.3ms)
  User Load (0.1ms)  SELECT "users".* FROM "users" LIMIT 10
  Rendered users/_user.html.erb (1.1ms)
  Rendered layouts/application.html.erb (3.0ms)
Completed 200 OK in 22ms (Views: 19.6ms | ActiveRecord: 1.0ms)


Started GET "/assets/application.css" for 127.0.0.1 at 2013-01-11 15:07:52 +0800
Served asset /application.css - 304 Not Modified (4ms)


Started GET "/assets/application.js" for 127.0.0.1 at 2013-01-11 15:07:52 +0800
Served asset /application.js - 304 Not Modified (2ms)


77

我之前试用过这个方法,也发现有这样的问题

De6df3

#4楼 @wuwx 我少打了几个字... 我的意思是让你自己把 @topics 打印出来看看每次的内容是否是相同的,简单方法直接做个 MD5 看看每次的值是不是相同的

不用发布上来,你确定内容是否有变化就好了

2963
@topics = Topic.includes(:user).page(1).reverse_order
Digest::MD5.hexdigest(@topics)

报告错误:TypeError: can't convert ActiveRecord::Relation into String

2963

#8楼 @huacnlee 果然好使了,厉害

2963

最后把控制器改成这样了:

def index
  @topics = Topic.includes(:user).page(params[:page]).reverse_order.all
  fresh_when(:etag => [@topics])
end
15

@huacnlee fresh_when 怎么搞能把 cell 里的数据也计算上

15

另外 @huacnlee 刚才发了帖子后 帖子创建成功. 这个notice一直在我发的帖子上,并且,304致使阅读次数也不变化了

De6df3

#12楼 @huobazi 这个是我忘了把 flash 加入 etag 的计算里面

De6df3

#11楼 @huobazi 这个就麻烦了,还没想过

674

@wuwx @huacnlee 上面处理有一个问题想问一下,@topics = Topic.includes(:user).page(1).reverse_order 这是一个延迟查询,@topics = Topic.includes(:user).page(params[:page]).reverse_order.all 这是真正去查询了数据了,如果页面做了片段缓存,那么 @topics = Topic.includes(:user).page(1).reverse_order 将不会查询数据,但是进行了内容的传输,没有用到本地浏览器缓存,@topics = Topic.includes(:user).page(params[:page]).reverse_order.all 也查了数据库,但是用到了本地浏览器缓存

674

@wuwx @huacnlee 为什么 ActiveRecord::Relation 每次查询出来的不一样啊?

674

@wuwx @huacnlee 说的具体一点就是,Digest::MD5.hexdigest(ActiveRecord::Relation) 每次的结果不一样

674

@wuwx @huacnlee 我想问一下为什么不一样

De6df3

#18楼 @josh_sulin 不一样应该是每次的 AREL 的 object_id 不同导致的。

fresh_when 并不是对整个内容做 MD5 的,而是挑了一些特别的属性,比如 Model 的 updated_at, id 等

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册