Rails.cache.fetch, символы и Memcached - PullRequest
       13

Rails.cache.fetch, символы и Memcached

2 голосов
/ 25 февраля 2010

У меня есть приложение rails 2.3.4 и строка, которая выглядит следующим образом:

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

и все работало нормально, пока я не решил переключить слой кэширования на memcached, добавив в свою среду следующее: rb:

config.cache_store = :mem_cache_store

Теперь строка, которая работала нормально, выдает мне следующую ошибку:

 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'

Я понимаю ошибку, но я бы предположил, что этот общий случай был бы быстро обнаружен тестовым примером рельсов, поэтому мне интересно, делаю ли я что-то не так. В противном случае я уверен, что смогу решить эту проблему, чтобы преобразовать символ в строку.

Спасибо

Ответы [ 2 ]

2 голосов
/ 25 февраля 2010

Просто используйте строковые ключи, если можете. Все примеры документации используют строковые ключи. Хотя это явно не упоминается, насколько я вижу, другие ключи не поддерживаются.

Ключевые аргументы передаются непосредственно в реализацию кеша, поэтому различные разновидности кеширования могут не совпадать по поводу того, принимают ли они что-либо кроме строк.

Поскольку кэши являются внешними, за исключением кэша в памяти, я не уверен, что вспомогательные символы были бы полезны, кроме предотвращения случаев, подобных вашему. Ключ на самом деле будет записан в какой-нибудь вывод (он не только внутренний для вашего приложения Ruby), поэтому концептуально ключ должен быть строкой.

Изменить в ответ на комментарий: Да, конечно, в этом случае вполне возможно и вполне разумно создать патч обезьяны, чтобы обойти необходимость изменения всех вызовов. Что вы предлагаете, так это (скопировано в ответ для удобства чтения):

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

Я бы также подумал о том, чтобы просто выполнить поиск и замену всего проекта для \.fetch(:\w+) и заменить его на \.fetch("$1") (при необходимости повторите для read и write). Вероятно, это должно охватывать 95% всех случаев, и последующий запуск вашего набора тестов должен перехватить остальные ошибки.

В целом: Хотя документация по Rails в наши дни довольно хороша, к сожалению, многие предположения все еще неявны. Как правило, рекомендуется внимательно изучить примеры, приведенные в документации, и использовать тот же стиль. Документированные примеры всегда показывают, как должна была использоваться платформа.

0 голосов
/ 07 марта 2010

FWIW, это канонически Rails.cache.read и Rails.cache.write.

...