Rails Memcached 可以用来缓存 json 吗?

hlcfan · 2012年03月10日 · 最后由 Rei 回复于 2012年03月14日 · 6067 次阅读

在 controller 里

Rails.cache.fetch("posts", :expires_in => 30.minutes) {
        @posts = Post.joins(:user).where('users.email = ?' ,email)
      }          
render :json => @posts

由于@posts 比较频繁的被调用 (这个是一个 API),所以我想使用缓存,不知道这样有没有作用. 如果把 render :json => @posts 放到里边,是不是会有作用?以下是代码:

Rails.cache.fetch("posts", :expires_in => 30.minutes) {
            @posts = Post.joins(:user).where('users.email = ?' ,email)
            render :json => @posts
          }     

求大牛们指教.

共收到 24 条回复

明显可以啊,不过你用法不对

@posts = Rails.cache.fetch("posts", :expires_in => 30.minutes) {
   Post.joins(:user).where('users.email = ?' ,email)
}
render :json => @posts

我晕还要传参数啊,参数要放入 cache_key

@posts = Rails.cache.fetch("posts:#{email}", :expires_in => 30.minutes)  do
Post.joins(:user).where('users.email = ?' ,email)
end
render :json => @posts

你好,render 写道括号外边?这个 action 是没有 view 的.

不能这样用。fetch 有缓存的时候 block 里的代码不执行,无缓存的时候返回并缓存 block 的返回值,所以无论那种情况都返回不了正确的值。

另外不同用户的数据不同,key 也要不同,见 #2 楼 @ywencn

谢谢各位,我第一次来 ruby-china,哇,气氛不错.我先去看看@ywencn 的 guides.

@ywencn @Rei 你们好,我看完 guides 了.有三个问题. 1.我这些代码是在 controller 里的.不能插写吧.像:"posts:#{email}" 2.由于这个 action 没有 view,所以 cache_key 有用吗? 3.这个是我做的一个 api,访问比较频繁,如果用 memcache,效果好吗?有更好的方法吗? 感谢大牛们! :-)

#7 楼 @hlcfan

  1. 这是 Ruby 的字符串语法,可以插
  2. cache_key 是 Rails.cache 用来存储 value 的,Rails.cache 在 Rails 范围都可以用
  3. memcache 很好

@Rei 非常感谢 :-)

补充一下

一般来说 json 接口不会直接用 to_json,因为输出的信息太多,这时可以用 Jbuilder https://github.com/rails/jbuilder 来定制 json 数据。Jbuilder 可以用视图的 helper。

我觉得缓存设在 View 比较好,AR 是延迟查询的,不会重复查询。(可能别人有不同见解)

#10 楼 @Rei @ywencn 一直比较关心缓存的问题, 如何利用 etag 和 rack-cache 进行缓存呢? 有没有比较好的例子

#10 @Rei 你好,那就是说我加一个 view,把 json 数据 render 到 view 里? 另外,什么 AR? :-)

#11 楼 @allenwei 官方例子很简短 http://guides.rubyonrails.org/caching_with_rails.html#conditional-get-support

#12 楼 @hlcfan 是的,用 Jbuilder 渲染;AR 是 ActiveRecord 简称。

@ywencn 你好,我已经将数据存到 memcache 里了,但是不知道在 view 里怎么取出来.= =|||

#14 楼 @hlcfan fetch 就 fetch 行了,有缓存自动读。get 的时候 key 跟 fetch 的 key 一样。

可以看看 ActiveSupport::Cache 下面的代码,很短的。

#15 楼 @Rei @Rei 你好,我看 console 里的记录.每次他都会删除已有的记录,set 新的记录,然后 get. 怎样不用每次都 fetch 新的?直接从 cache 读?

#16 楼 @hlcfan 可能是开发环境没有打开 cache

config/enviroments/development.rb 里面有个

config.action_controller.perform_caching = false

设 true 重启看看

#15 楼 @Rei 你好,我写了这句,你看效果好吗? value = Rails.cache.read("posts-#{params[:email]}-#{params[:seckey]}") return value if value Rails.cache.fetch("labels-#{params[:email]}-#{params[:seckey]}", :expires_in => 30.minutes) { blah blah blah......

#17 楼 @Rei 你好,config.action_controller.perform_caching 是 true.

#18 楼 @hlcfan 正常来说只要 fetch 就好了。

只保留 fetch,把 log 打出来看看?

#10 楼 @Rei 你好,非常感谢你的热心帮助,问题已经解决.关于 10 楼,我想知道.view 层的缓存,是 page cache 吗?

#21 楼 @hlcfan view 里面的 cache 指 Fragment Cache ,是粒度小比较灵活的 cache。 Page cache 是框架内粒度最大的 cache,没有走过滤器和控制器。

可以抽时间看一下 http://guides.rubyonrails.org/caching_with_rails.html

#22 楼 @Rei 你好,那你所说的就是 fragment cache 了?

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