I have been doing some RubyOnRails stuff lately, for fun basically. I decided to build my new site (supersole.net) with Rails, and I also decided to use the shiny REST stuff which comes built in with the latest versions of Rails.
But I don’t know if it’s just me and my (mis)understanding of how this is supposed to work, but I’m fighting with the framework more than desired. The main problem is not with REST, and is not with caching either, but with both at the same time.
I have a controller (PostsController), whose index action takes care of showing the latest posts if an html response was required, and the RSS feed if the rss format was required. Until here, it’s all fine, I set :cache_action to :index and it was generating beatiful posts.cache and posts.rss.cache versions. The problem came when I decided to add an “archive” view of the index page: it would allow me to show a list with all the posts in the site, using a url like /posts?type=archive. In the code, if type==archive, it would retrieve every post and show only the titles plus a link; in any other cases it would have the normal behaviour.
Ahh but how to discern what to cache this time? If I visited first the archived version and then went to the non-archived view, I found the cache was showing the same contents for both /posts and /posts?type=archive. The feed was correctly cached, though.
Then I switched to manually cache the fragments, specifying the type (archive/index) and the request format (html or rss) as params for the cache, but with no luck, since I couldn’t find a way of caching the rxml output, although the different html versions were working well in this case, with two different versions being generated.
It could be a bad approach on my side, also. Maybe I’m putting just too much logic into what should be a neater function. The only idea that comes to mind is a PostsArchive resource which would show all the posts and could then be easily cached (would be just a single page!), but it looks a bit exaggerated to create a new Controller just for showing a listing of posts, since in fact it is simply another view of the same resource.
Again, I understood that the philosophy of REST in Rails was to have many simple controllers rather than a handful of complex controllers, and while I am all in favour of that concept, it is still a bit complicated to put those little controllers in place in a meaningful way.

Lourens
Hi,
See http://blog.craz8.com/action-cache-plugin/ … supports scoping via per controller cache keys.
Yan
One thing to try is to use routes, which will not only make your urls’ prettier but make the caching work automatically. So turn /posts?type=archives into /posts/archive. Also check out this plugin: http://agilewebdevelopment.com/plugins/action_cache, it may help with some things. I have not done exactly what you’re doing here yet though so these are just general hints…
Brian
Instead of using GET parameters, use the extra routing in map.resources.
map.resources :posts, :collection => { :archive => :get }
This will get you:
GET /posts => PostsController#index
and
GET /posts/archive => PostsController#archive
Raul
I didn’t tried caching yet but as far as I know it doesn’t play nice with those ugly ?param=value parameters. Maybe you could modify your routes.rb to something like this:
map.connect ‘posts-archive/’,
:controller => ‘posts’,
:action => ‘index’,
:type => ‘archive’
This way you would preserve your controller and action and get a new clean -and hopefully cacheable- URL.
Ben
Perhaps the easiest solution is just to add an “archive” action to your PostsController and update the routing as follows:
map.resources :posts, :collection => { :archive => :get }
Alternatively you could try the action_cache plugin (http://agilewebdevelopment.com/plugins/action_cache), this allows you to overide the cache key (hence allowing the URL parameter to be stored).
sole
Thanks guys! It might be good since both of you pointed to the same solution :-)