按照 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 了,这个是为什么呢
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)
@topics = Topic.includes(:user).page(1).reverse_order
Digest::MD5.hexdigest(@topics)
报告错误:TypeError: can't convert ActiveRecord::Relation into String
最后把控制器改成这样了:
def index
@topics = Topic.includes(:user).page(params[:page]).reverse_order.all
fresh_when(:etag => [@topics])
end
@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 也查了数据库,但是用到了本地浏览器缓存
#18 楼 @josh_sulin 不一样应该是每次的 AREL 的 object_id 不同导致的。
fresh_when 并不是对整个内容做 MD5 的,而是挑了一些特别的属性,比如 Model 的 updated_at, id 等