timed_fragment_cache on Rails 2.1

With Rails 2.1 cache_erb_fragment has been replaced by write_fragment. This breaks a plugin I really enjoy to use: timed_fragment_cache by Richard Livsey.

It basically allows you to specify an expiry for the fragments you cache, e.g. inside memcache, by adding a "meta" fragment for the fragment you store containing the expiry time.

Some usage examples - pretty self-explaining:

In your view:

<%- cache 'my_key', 1.hour.from_now do -%>
	...
<%- end -%>

With extensive queries - your view ...:

<%- cache 'some_posts' -%>
	<%- @posts.each do |post| -%>
		<%= @post.title %>
	<%- end -%>
<%- end -%>

... and your controller:

when_fragment_expired 'some_posts', 1.hour.from_now do
	@posts = Post.find( :all )
end

Since timed_fragment_cache is so convient to use and essentially because I simply cannot live without it, I've fixed Richards version to work with Rails 2.1, i.e. let it use write_fragment instead of cache_erb_fragment.

Download version 0.2.

Trackback URL for this post:

http://www.ruzee.com/trackback/154

Good work this is a great plugin. I've

Good work this is a great plugin. I've forked the original in github with your changes (http://github.com/GeorgePalmer/timed_fragment_cache/tree/master)

[...] patches on the

[...] patches on the timed_fragment_cache [...]

Hmm... looks like the template tags got

Hmm... looks like the template tags got swallowed up. Here's the template code that failed:

elsif @aggregate_feed
cache 'aggregate_feed', Time.now + 15.minutes do
What we're blogging about
...etc.

Hi, Thanks for the plugin and the

Hi,

Thanks for the plugin and the notes from everybody. I just installed it into my site, and it's awesome to experience the 100x speedup one can get by caching database hits. (My home page has lots of dynamic content, but it's all cached depending on the type of data: http://greenfabric.com/ )

I have a couple of notes about the package:

1) The package has a stray ".svn" directory in /lib, which I didn't notice at first, and which caused havoc with my svn set-up, until I figured out what was going on. This should probably be deleted.

2) A note for other beginners, like me, maybe: With Rails 2.1, the statements in the templates ALSO need to have that "Time +" syntax described above. For example, I cache an aggregate rss feed with this code in my template:

cache 'aggregate_feed', Time.now + 15.minutes do

...and this code in my controller:

when_fragment_expired 'aggregate_feed', Time.now + 15.minutes do

I saw in the docs that it's possible to leave out the time in the template if it's being used in the controller, but I haven't tested it.

3) Another note for beginners - not about this change to the plugin, per se. I had a problem with the RSS feed because I don't display it on every page, and my template checks for the presence of this @aggregate_feed variable. This template code:

What we're blogging about

...failed, displaying nothing, because the @aggregate_feed was no longer being set by the controller (since the controller saw it was still cached.)

My solution was to change the controller code to this:

@aggregate_feed = true
when_fragment_expired 'aggregate_feed', Time.now + 15.minutes do
@aggregate_feed = CreativeRole.aggregate_feed
end

This now at least fulfills the "flag" function that the variable had, in order to let the cached version of the feed be shown. The results of this -- the feed, can be seen in the right side-bar of my site that I mentioned above.

Sorry, but the above is not a good

Sorry, but the above is not a good workround since the conversion from TimeZone to Time causes trouble when it comes to calculate if the cache is expired. The best solution I can think of is to use:

when_fragment_expired ‘tags_home_page’, Time.now + 10.minutes do

That way it is just the Time class being used as in Rails 2.0.

A workround seems to be that instead of

A workround seems to be that instead of in your controller having:

when_fragment_expired 'tags_home_page', 10.minutes.from_now do

we put:

when_fragment_expired 'tags_home_page', 10.minutes.from_now.time do

So instead of passing a TimeZone object, we pass Time as normal. Not elegant I know...

Excellent, that's a great fix. The

Excellent, that's a great fix. The plugin is brilliant unfortunately there is one other issue with Rails 2.1. It occurs if config.time_zone is set in the environment.rb and results in an error:

private method gsub called for StringIO
time_with_zone.rb:118:in to_yaml

If I find a fix for this, I'll re-post. Cheers.

This is great! Has this been submitted

This is great! Has this been submitted to Richard for inclusion into the plugin?

Glad you find it useful! The plugins

Glad you find it useful!

The plugins are all on github now (http://github.com/rlivsey) which should help them stay updated a bit easier.

If you send a patch over with the fix in (or fork and issue a pull request), I'll merge the changes in there so that everyone can benefit.

Thanks.