[typo] Towards fragment tracking

Piers Cawley pdcawley at bofh.org.uk
Tue Oct 11 02:37:33 EDT 2005

Talking with slaird on IRC I volunteered to write up some design notes for the
list on my ideas about how to do cache tracking.

At present, whenever anything changes in the database, we simply zap everything
in the cache. This is, um, inefficient...

What we need is a mapping between our cached views/fragments and the models
that contribute to them. How do we arrange things?

Here's a proposal:

We extend the Content class so that all attributes declared with
'content_fields' can take an optional argument, :controller. The basic accessor
method would look like:

  def body(controller=NullController.instance)

We also declare a new relationship:

  Content.has_and_belongs_to_many :dependents, :class => FragmentPath

Meanwhile, the controller keeps track of the fragment path that's currently
being rendered (or possibly, if we're caching nested fragments, the list of
fragments we're currently rendering) and defines 

  def depends_on(content)
    if current_fragment

Now, assuming we capture all the appropriate content attributes (more than just
body and extended) we have a nice, reliable mapping between content objects and
html fragments, so our cache sweeper can look something like:

  class ContentSweeper < ActionController::Caching::Sweeper
    def after_save(content)

    def after_destroy(content)


    def expire_dependents(content)
      content.dependents.each do |fragment|
        expire_fragment fragment.to_s

But what about when comments get added? How do we handle that? I hear you ask.
Easy, we do what we should have been doing for a while now:

  Comment.belongs_to :article, :counter_cache => true
  Trackback.belongs_to :article, :counter_cache => true

and add comment_count and trackback_count columns to the contents table. Now,
whenever we add a comment, the article itself gets saved and, as if by magic,
the appropriate cached fragments get flushed.

Note that there's been a certain amount of handwaving about precisely how the
controller tracks the current fragment, but that implementation detail doesn't
really affect how we make this work.

So, comments? Questions? Corrections?

Piers Cawley <pdcawley at bofh.org.uk>

More information about the Typo-list mailing list