views:

724

answers:

2

I have a rails 2.3.4 app and a line that looks like:

temp = Rails.cache.fetch(:temp_id) { User.find_by_name('Temp').id } 

and everything worked fine, until I decided to switch the caching layer to memcached by adding the following to my environment.rb:

config.cache_store = :mem_cache_store

Now the line which used to work fine gives me the following error:

 undefined method 'length' for :temp_id:Symbol           

/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_support/vendor/memcache-client-1.7.4/memcache.rb:645:in 'get_server_for_key'

I understand the error, but I would imagine this common case would have been quickly discovered by a rails test case, so I am wondering if I am doing something wrong. Otherwise, I'm sure I can monkeypatch this issue to convert the symbol to a string.

Thanks

+1  A: 

Just use string keys if you can. All the documentation examples use string keys. Although it's not explicitly mentioned as far as I can see, other keys are not supported.

The key arguments are passed directly to the cache implementation, so the different caching flavours may disagree on whether or not they accept anything other than strings.

Because the caches are external with the exception of in-memory cache, I'm not sure that supporting symbols would be useful apart from preventing cases like yours. The key will actually be written to some output somewhere (it's not just internal to your Ruby app), so conceptually the key should be a string.

Edit in reaction to comment: yes, it is of course possible and perfectly reasonable in this case to create a monkey patch to circumvent having to change all calls. What you're suggesting is this (copied into the answer for readability):

class MemCache
  def get_server_for_key_with_symbols(key, options = {})
    key = key.to_s if key.is_a? Symbol
    get_server_for_key_without_symbols(key, options)
  end
  alias_method_chain :get_server_for_key, :symbols
end

I would also consider just doing a project wide search-and-replace for \.fetch(:\w+) and replace it with \.fetch("$1") (repeat for read and write if necessary). This should probably cover 95% of all cases and a subsequent run of your test suite should catch the rest of the errors.

In general: While the documentation of Rails is pretty good these days, a lot of assumptions are unfortunately still implicit. It's generally a good idea to take a good look at the examples that are given in the documentation, and use the same style. The documented examples are always how the framework was intended to be used.

molf
using string keys may seem like the obvious solution, but the frustrating part is that since symbols worked initially, all of my cache statements use symbol.At this point its just easier to monkey patch, something like this seems to work:#this is to be able to use symbols for rails.cacheclass MemCache def get_server_for_key_with_symbols(key, options = {}) key = key.to_s if key.is_a? Symbol get_server_for_key_without_symbols(key, options) end alias_method_chain :get_server_for_key, :symbols end
gmoniey
thanks for cleaning up the editing of my monkey patch. Seems that you can't do styling in comments.To be honest, the only reason I don't want to do a project wide search and replace is that I feel symbols provide more readability. Obviously this is completely a personal preference, and ties in heavily to my code editor.Thanks.
gmoniey
You `can too` do *styling* in **comments**. Mostly.
Sai Emrys
A: 

FWIW, it's canonically Rails.cache.read and Rails.cache.write.

Sai Emrys