Cache the output of an action on a per-format & per-user basis

Ryan Bates' render-caching gem is nice, but it keys cache entries by request_uris:

def render_with_cache(key = nil, options = nil)
  key ||= request.request_uri     #  <----
  body = Rails.cache.read(key)
  if body
    render :text => body
  else
    yield if block_given?
    render unless performed?
    Rails.cache.write(key, response.body, options)
  end
end

This is an incomplete solution since what my application renders for a given URI varies based on:

  1. The current user
  2. The format of the request (html, js, atom)

How can I modify this method take the current user and request format into account?

Answers


The method accepts a key argument, thus you don't need to hack it. Simply pass your cache name as argument.

render_with_cache([current_user.id, request.format, request.uri].join("/")) do
  # ...
end

If you often find yourself calling the method with this argument, creare a new method which wraps the previous one.

def render_with_cache_scoped_by_user(key = nil, options = nil, &block)
  scoped_key = [current_user.id, request.format, request.uri]
  scoped_key << key unless key.blank?
  render_with_cache(scoped_key.join("/"), options, &block)
end

Need Your Help

Can composite states contain do actions?

uml statechart

I know that composite states are composed of internal states which show how the state behaves. Can you also have a do action when the state is active? this is like showing parallel behavior in the...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.