清单 4. 选项卡的路由规则
map.connect 'member/:id/:tab', :controller => 'profiles', :action => 'show'
对于具有页面参数的那些列表以及依赖于 URL 参数的其他页面,也需要采用相同的做法。此外,还需要考虑安全性问题。
如果页面已经在缓存内,那么就不会用到 Rails 框架,服务器并不能为您管理安全性。Web 服务器将更乐于在缓存内呈现任何页面,而不管用户是否对其拥有查看的权限。所以,如果您很关心页面可由谁查看,那么就不要使用页面缓存。
如果只是想缓存简单的静态页面,那么了解上述内容就应该足够了。只要内容简单,实现起来就不难。
当想要缓存更为复杂的内容时,就需要进行一些权衡取舍了。由于想要缓存的页面高度动态,所以到期失效逻辑就会变得更加复杂。要处理复杂的到期失效逻辑,将需要编写和配置定制清理器(sweeper)。在某些控制器击发时,这些类会从缓存内删除选定的元素。
多数定制清理器都会观察某些模型对象,并根据更改击发逻辑来使一个或多个缓存页面到期失效。清单 5 显示了一种典型的缓存清理器。在此清理器中,开发人员可以定义一个活动记录事件,比如 after_save。当此事件击发时,清理器也会击发,并可让缓存内的特定页面到期失效。这个事例所显示的到期失效基于 expire_page 方法。而很多严格的应用程序大都直接使用 Ruby 优秀的文件系统实用工具来显式地删除所缓存的页面。
清单 5. 一个典型的观察器
class CauseController < ApplicationController
cache_sweeper :cause_sweeper
...
class CauseSweeper < ActionController::Caching::Sweeper
observe Cause
def after_save(record)
expire_page(:controller => 'causes', :action => 'show',
:id => record.id)
cause.nonprofits.each do |nonprofit|
expire_page(:controller => 'nonprofits', :action => 'show',
:id => nonprofit.id)
end
end
end
现在,您可能会开始感觉到页面缓存的些许缺点了:复杂性。您虽然可以很好地进行页面级的缓存,但固有的复杂性却让应用程序很难测试,进而会增加系统内出现 bug 的可能性。而且,如果页面针对每个用户都会有所不同,或者希望缓存进行过身份验证的页面,那么将需要使用页面缓存之外的方式。对于 ChangingThePresent,我们必须处理两种情况,原因是我们必须基于用户是否登录来更改基本布局上的链接。对于大多数页面,我们甚至都不会考虑使用页面级缓存。为了让您能够深入了解页面级的缓存,在本文的 参考资料 部分,我特意给出了到一系列有关页面级缓存的优秀文章的链接。接下来,将来深入探究另一种形式的整页缓存 —— 动作缓存。










