Sweeper实例

expir_xxx 方法会工作的很好,但是在你的“控制器”中它们也要与缓存功能的代码合
作。每次你修改数据库内的一些东西时,你也必须对它可能影响到的被缓存页做些工作。在
应用程序较小时这很容易,但应用程序快速增长时这就会变得很困难。在一个“控制器”内
的修改可能会影响到另一个“控制器”中被缓存的页。“帮助方法”内的商业逻辑,其实不
应该知道有关HTML 页的信息,现在需要担心的是失效被缓存的页。
幸运地,Rails 可以使用sweeper 来简化一些这样的耦合。Sweeper 是你的“模型”对象
上的一个指定“观察者”。当在“模型”内有重要事情发生时,sweeper 会失效依赖于此“模型”数据的被缓存的页。你的应用程序可以根据需要许多sweeper。典型地你会创建一个单独的sweeper 来管理每个“控制器”的缓存。在app/models 目录内放置你的sweeper 代码。

class ArticleSweeper < ActionController::Caching::Sweeper
observe Article

# If we create a new article, the public list
# of articles must be regenerated

def after_create(article)
expire_public_page
end

# If we update an existing article, the cached version
# of that particular article becomes stale

def after_update(article)
expire_article_page(article.id)
end

# Deleting a page means we update the public list
# and blow away the cached article

def after_destroy(article)
expire_public_page
expire_article_page(article.id)
end

private
def expire_public_page
expire_page(:controller => "content", :action => 'public_content')
end

def expire_article_page(article_id)
expire_action(:controller => "content",
:action => "premium_content",:id => article_id)
end

end
sweeper 的工作流程有点费解。

1、sweeper 在一个或多个“活动记录”类上被定义为一个“观察者”。在这个例子中,
它观察Article“模型”(我们在270 页谈论它)。sweeper 使用“钩子”方法来适当地失效被缓存的页。

2、sweeper 也被在一个“控制器”中像下面一样被声明为活跃的。
cache_sweeper directive.
class ContentController < ApplicationController
before_filter :verify_premium_user, :except => :public_content
caches_page :public_content
caches_action :premium_content
cache_sweeper :article_sweeper,
:only => [ :create_article,
:update_article,
:delete_article ]
# ...

3、如果请求来自sweeper 过滤的“动作”中的一个的调用,则sweeper 被激活。如果任
何一个“活动记录”观察者方法被激活,则页和“动作”失效方法将被调用。如果“活动记
录”观察者得到调用,但是当前“动作”没有被选择为一个缓存的sweeper,则sweeper 内
的失效调用被忽略。否则失效有效。

实例
sweeper插件用于自动生成清扫缓存的sweeper类,监视特定的model,根据相应的事件触发其行动,下面是一个example:

1. 首先生成项目和初始数据:
$ rails test_sweeper
$ cd test_sweeper
$ script/generate scaffold post title:string body:text

[/color]
#db/migrate/001_create_posts.rb
(1..50).each do |num|
  Post.create(:title => "test#{num}", :body => "Test#{num}")
end

$ rake db:migrate

2. 安装插件:
$ script/plugin install http://topfunky.net/svn/plugins/sweeper

3. 生成Sweeper类,该类在model增删改之后将缓存页面清除:
$ script/generate sweeper post after_save before_destroy

[color=red]

#app/models/post_sweeper.rb
class PostSweeper < ActionController::Caching::Sweeper
  observe Post
  def after_save(record)
    expire_page :controller => 'posts', :action => 'index'  
  end
  def before_destroy(record)
    expire_page :controller => 'posts', :action => 'index'  
  end
end


4. 在controller中指定缓存页面和sweeper类:
[color=red][/color]
#app/controller/posts_controller.rb
caches_page :index
cache_sweeper :post_sweeper


5. 察看效果:
当第一次访问/posts时,server会查询数据库,render页面,并生成cache page:
Cached page: /posts.html (0.00737)
之后再访问/posts时,server就不会再去查询数据库,render页面,而直接去读cache page
直到我们对post做了增删改中任意一个操作,server会删除被cache的page:
Expired page: /posts.html (0.00014)
然后再访问/posts时,server又会去查询数据库,render页面,并生成cache page

你可能感兴趣的:(工作,cache,SVN,活动,Rails)