4

如何使用来自另一个控制器的文件扩展名 (.json) 使缓存中的片段过期?

我正在使用 Rails 3.2.8。

我有两个相同型号的控制器:/admin/books_controller 和 /api/books_controller。管理控制器用于创建/更新/删除书籍并需要提升访问权限。api/books_controller 用于搜索/列出用户关于一本书的详细信息。我试图缓存 api/books_controller

class Api::BooksController < ApiController
  caches_action :show

  def show    
    @book = Book.find(params[:id])
  end
end

这很好用。第一个请求很慢,第二个请求很快

Rendered api/books/show.json.rabl (119.7ms)
Write fragment views/localhost:3000/api/books/4.json (1.7ms)
Completed 200 OK in 568ms (Views: 124.2ms | ActiveRecord: 9.5ms)

Read fragment views/localhost:3000/api/books/4.json (0.2ms)
Completed 200 OK in 16ms (ActiveRecord: 2.6ms)

现在,当书被更新或销毁时,我需要使碎片过期。我有这个:

class Admin::BooksController < AdminController

  def update
    @book.attributes = params[:book]
    if (@book.save)
      expire_action(:controller => 'api/books', :action => 'show', :id => @book.id, :format => 'json')
    end
  end

end

但是,这不会解析到相同的片段(请求现在是 HTML 请求,发送到不同的控制器):

Started PUT "/admin/books/4" for 127.0.0.1 at 2012-11-08 12:27:11 -0600
Processing by Admin::BooksController#update as HTML
...
Expire fragment views/localhost:3000/api/books/4 (0.1ms)

我的带有 JSON 请求的 API 控制器读取和写入此片段:

views/localhost:3000/api/books/4.json

我的管理控制器试图使这个片段过期:

views/localhost:3000/api/books/4

如何使用不同的请求格式从另一个控制器过期 views/localhost:3000/api/books/4.json?

这个问题:rails 3 caching: expire action for named route表示我可以使用正则表达式使多个片段过期,但这需要缓存中的键是可枚举的(http://api.rubyonrails.org/classes/ActionController/Caching /Fragments.html#method-i-expire_fragment )

4

1 回答 1

0

看来问题出在路由设置默认参数上。在 API 控制器中,params[:format] 为 'json',而在 Admin 控制器中为 nil。

当我将此添加到我的管理控制器时:

params[:format] = 'json'
expire_action(:controller => 'api/books', :action => 'show', :id => @book.id, :format => 'json')

然后,两个控制器中的片段匹配。

这让我回到了我的路线:

在我的路线中,我有这个:

namespace :api, :defaults => {:format => 'json'} do
  resources :books, :only => [:show]
end

这导致 params[:format] 在我的 api 命名空间中设置。我的管理命名空间中没有任何内容,显然 actionpack/ActionCachePath 对这两者的看法不同。删除路由中的默认值解决了这个问题。

于 2012-11-08T19:21:19.057 回答