#143 open
Michael Klishin (antares)

merb-cache does not consider params when generating keys

Reported by Michael Klishin (antares) | May 20th, 2008 @ 11:41 AM | in 0.9.7

From Merb google group:

private method _cache_action (for

cache_page/cache_action controller filters) does not consider params

when generating keys. instead of using request.path it could call the

key_for method to dry things up and/or provide a hook for custom key

gens (ex. in case you wanted to include session id).

so if uri is /items/list/apples?order=name&filter=brand

now:

/items/show/apples.html

with params:

/items/show/apples_order_name_filter_brand.html

or md5 hash:

/items/show/aslf323lkj3klj234l3sdfg3.html

Comments and changes to this ticket

  • Ben Chiu

    Ben Chiu May 20th, 2008 @ 04:46 PM

    this would be nice in merB==>

    (code is untested)

    1. :cache_key_format => :md5_hash|:snake_case)
    2. :cache_key_format => "/:controller/:action/foo/:id/bar")
    3. :cache_key_format => "/:controller/:action/foo_:id_bar_:format")

    def key_for(options, controller, controller_based = false)

    key = ""

    if key_format = @config[:cache_key_format] && controller_based

    case key_format

    when :hashed

    key = request.path.chomp("/")

    key = "index" if path.empty?

    key += "/" + Digest::MD5.hexdigest(params.to_s)

    when :snake_case

    key = request.path.chomp("/")

    key = "index" if path.empty?

    key += ("_" + request.query_string.gsub(/[&=]/,'_')).chomp('_')

    else

    params.each {|k,v| key_format.sub(":#{k}", v.gsub(/[^a-z0-9\/

    \.]/,'_') }

    key = key_format

    end

    elsif options.is_a? Hash

    case

    when key = options[:key]

    when action = options[:action]

    controller = options[:controller] || controller

    key = "/#{controller}/#{action}"

    end

    if _params = options[:params]

    key += "/" + _params.join("/")

    end

    else

    key = controller_based ? "/#{controller}/#{options}" : options

    end

    key

    end

  • booss

    booss May 26th, 2008 @ 08:03 AM

    Hi,

    merb-cache was designed with "clean urls" in mind.

    Using the query string is a pain because you have to escape the string and there would be empty params like "format=&id=" that might confuse cache_get/cache_set in case they are here or not.

    If you use clean urls then you're safe.

    The MD5 digest thing is interesting though...

    I'll give it a try.

    Anyway, thanks for reporting !

    Cheers,

    booss

  • Ben Chiu

    Ben Chiu May 26th, 2008 @ 12:42 PM

    i agree, clean urls are the ideal. however, there are many real-world cases where ppl would use querystring.

    lets say an app has a list action. items in this list can be sorted and narrowed down with filters. resulting url would something like:

    /items/list/apples?order=name&page=2&filter1[brand]=mac&filter2[color]=red

    there could be up to N different filters. writing routes for all of them would be messy. the url is called by ajax get and form.serialize. also, merb/will paginate will build query strings for subsequent pages. you can see what i'm getting at.

    i'm working on a patch. i'll let you guys decide whether or not it fits in with the framework.

    thanks,

    ben

  • Ben Chiu

    Ben Chiu May 27th, 2008 @ 09:05 AM

    === 0.9.4 merb-cache patch, released 2008-05-27:

    • note: this patch depends on a couple patches to

    merb-core test (dispatch_to) and request

    (query_parse, params_to_query_string)

    • support query string params:
    • generate unique keys when params are present
    • retain existing behavior when they are not
    • preserve order of query params
    • patch merb-core request methods query_parse

    and params_to_query_string to allow use of

    Dictionary (ie. preserve order)

    • allow :params => false to disable inclusion
    • support out-of-the-box compatibility with

    merb_paginate

    • change default key format from tree to snake

    pairs (tree can be cpu intensive and expose

    filesystem problems on deep nested keys)

    • added dependency 'digest/md5'
    • DRY out action/page cache methods:
    • unify use of key_for instead of request.path
    • sanitize_cache_key method:
    • remove illegal posix/win32 filesystem chars
    • designed to be overridden by user to help

    match urls on nginx/apache

    • added global config settings:
    • cache_action_ttl - action cache expiry time
    • cache_page_ttl - page cache expiry time
    • cache_key_format - cache key style/format
    • added options to controller caching:
    • :format - key format (overrides global config)
    • :params - include only these params
    • fix multiple cache_pages, cache_actions:
    • allow combinations of arrays and symbols
    • provide :all option for action/page caching:
    • makes all actions in controller cacheable
    • use :exclude option to exclude actions
    • statment must appear at end of class declaration
    • support various key formats:
    • nil - default snake case using param key-pairs
    • :snake - snake case using param values
    • :hash - MD5 hashed key
    • :query - escaped querystring
    • :tree - folder tree (limited to 10 levels)
    • custom - ":paramname1/:paramname2_and_:paramname3"

    where param names are substituted by their values

    • add rspecs tests with params
    • patch merb-core test request helper to allow

    querystring to be passed in without being

    overwritten by fake dispatch

    • remove :id and :format params from query string

    (they would not be there unless specifically

    called like "?id=1&format=html")

    • key generator tests for simple/complex urls
    • add controller actions with params
    • page/action cache and expiration tests with params
    • modified some existing tests to use new default

    snake case key format

    • to do:
    • make multiple cache :all work whether or not

    statement comes before or after methods in

    controller class declaration

    • polish up comments/examples
  • Ben Chiu
  • Ben Chiu

    Ben Chiu May 27th, 2008 @ 09:12 AM

    • no changes were found...
  • Ben Chiu

    Ben Chiu May 27th, 2008 @ 09:21 AM

    comment didn't format properly (i don't use textile). wish there was a preview mode. pls read CHANGELOG (attached). tks.

  • Michael Klishin (antares)

    Michael Klishin (antares) August 2nd, 2008 @ 01:51 PM

      • → Assigned user changed from “” to “Daniel Neighman (hassox)”
      • → State changed from “new” to “open”
      • → Tag changed from “” to “merb-cache patch”
      • → Milestone changed from “1.0” to “0.9.7”

Please Login or create a free account to add a new comment.

You can update this ticket by sending an email to from your email client. (help)

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

Shared Ticket Bins