2

我有一个 rails 2.3.4 应用程序和一行如下所示:

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

一切正常,直到我决定通过将以下内容添加到我的 environment.rb 来将缓存层切换到 memcached:

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'

我理解这个错误,但我想这个常见的情况会很快被 Rails 测试用例发现,所以我想知道我是否做错了什么。否则,我确定我可以对这个问题进行猴子补丁以将符号转换为字符串。

谢谢

4

2 回答 2

2

如果可以,请使用字符串键。所有文档示例都使用字符串键。尽管据我所知没有明确提及,但不支持其他键。

关键参数直接传递给缓存实现,因此不同的缓存风格可能会在它们是否接受字符串以外的任何内容上存在分歧。

因为缓存是外部的,内存缓存除外,所以我不确定除了防止像你这样的情况之外,支持符号是否有用。密钥实际上会被写入某处的某个输出(它不仅仅是 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")(重复readwrite如有必要)。这可能应该涵盖所有情况的 95%,并且您的测试套件的后续运行应该会捕获其余的错误。

总的来说:虽然现在 Rails 的文档非常好,但不幸的是,许多假设仍然是隐含的。仔细查看文档中给出的示例并使用相同的样式通常是一个好主意。记录的示例始终是该框架的预期使用方式。

于 2010-02-25T07:36:57.920 回答
-2

FWIW,它是规范的 Rails.cache.read 和 Rails.cache.write。

于 2010-03-07T07:46:45.097 回答