Brian
Brian

Reputation: 6071

Rails Memcached Usage

I'm looking into using memcached for my rails application. I was considering using it on my member search, but I am confused because there are multiple parameters for the search which will be changing through user selection.

This is an example of a query for the search:

 @results = Painter.city(params[:city].downcase).state(params[:state]).tools(tools).transportation(trans).travel_distance(params[:travel_distance]).insurance(insurance).employee(emp).subcontractor(sub).available(true).paginate(:page => params[:page], :per_page => 20).where("premium = ? AND banned = ?", false, false).order('last_name')

This seems like a likely candidate for memcached, but I am unsure.

Please provide direction.

Upvotes: 1

Views: 220

Answers (1)

Stuart M
Stuart M

Reputation: 11588

You could certainly cache this using Memcached. You must start by deciding on a format for your cache keys, and when you have several different criteria/fields that uniquely determine a cache record (such as in your case) you can probably just concatenate them in a pre-determined order, using some kind of string to separate them. For instance, your cache key may look like this:

@results = Rails.cache.fetch([params[:city].downcase,
                   params[:state],
                   tools,
                   trans,
                   params[:travel_distance],
                   insurance,
                   emp,
                   sub,
                   params[:page]
                  ].join('/')) do
  Painter.city(params[:city].downcase)...  # rest of your query
end

You may want to tweak or clean up the format, but the gist of it is that you must be able to calculate a consistent cache key as a String. The easiest way to do that for multiple fields is to join them using a separator (I chose /, but you can use other separators if you choose.)

Note also that I left out the :per_page => 20, since that is hard-coded within your controller code and will not vary based on user input. If you decide to allow users to customize how many records are returned, you would need to include that in the cache key as well. Same goes for the where("premium = ? AND banned = ?", false, false) clause, and available(true).

You can use Rails caching for any kind of content that is non-trivial to look up from its original source (i.e., if it involves DB queries).

Of course a very important consideration to keep in mind is cache expiration: if/when you add new records to your DB that match the criteria of data you have in your cache, you must be sure to expire the data in your cache manually, or else set an automatic expiration when you write to the cache so that it will eventually be purged and refreshed on its own.

Using Memcached in Rails, manual expiration of the cache involves a delete:

Rails.cache.delete(key)

Or to use automatic expiration, use the :expires_in option:

Rails.cache.write(key, value, :expires_in => 1.minute)

Upvotes: 1

Related Questions