Caching of complex queries

This trick is great for actions which receive lots of parameters, for example – search controller. Obviously, you wouldn’t want to do that with something that receives a POST, but I omitted the check for it (using :if => {|controller| controller.request.get?} , for example), since I think that I know what I’m doing.
So the idea is to map all the parameters to some unique key, and then use that key as an :id for the url_for.

  # This caches the find action by the parameters
  require 'digest/sha1'
  caches_action :find, :expires_in => 10.minute,
    :cache_path => { |controller|
        search_key = Digest::SHA1.hexdigest(controller.params.inspect)
        logger.debug "Current search key: #{search_key}"
        controller.url_for(:action => 'find', :id => search_key)

The only minor issue that might arise, is that if you’re using pagination, the page number 1 when reached from the pagination links will have page=1 parameter, but when it’s initially presented, the parameter is absent. Adding such parameter won’t do any good, since the order of keys in hash in undefined. It’s possible, though, to build the key using some other technique, for example by massaging the request string. But since the case is quite rare, I think that any fix will be a waste of CPU cycles.

Leave a Reply