从传递给Rails.cache.fetch的块返回一个nil值会清除它吗?

时间:2012-10-15 08:26:39

标签: ruby-on-rails ruby-on-rails-3

假设我有一个这样的方法:

  def foo
    Rails.cache.fetch("cache_key", :expires_in => 60.minutes) do
      return_something
    end
  end

return_something有时会返回nil值。发生这种情况时,我不希望将nil值缓存60分钟。相反,下次我调用foo时,我希望传递给fetch的块再次执行。

默认情况下Rails.cache.fetch是这样的吗?或者我必须实现此功能吗?

更新(带答案)

事实证明,答案是否定的,至少在使用Memcached时。

3 个答案:

答案 0 :(得分:2)

它取决于您正在使用的缓存存储的实现。我会说它不应该缓存nil值,但空字符串可以缓存。

查看dalli store implementation即:

  def fetch(name, options=nil)
    options ||= {}
    name = expanded_key name

    if block_given?
      unless options[:force]
        entry = instrument(:read, name, options) do |payload|
          payload[:super_operation] = :fetch if payload
          read_entry(name, options)
        end
      end

      if !entry.nil?
        instrument(:fetch_hit, name, options) { |payload| }
        entry
      else
        result = instrument(:generate, name, options) do |payload|
          yield
        end
        write(name, result, options)
        result
      end
    else
      read(name, options)
    end
  end 

答案 1 :(得分:0)

此问题的更新答案是:默认情况下fetch缓存nil值,但使用dalli_store引擎可以使用cache_nils选项来避免它:

Rails.cache.fetch("cache_key", expires_in: 60.minutes, cache_nils: false) do
  return_something
end

答案 2 :(得分:0)

值得注意的是,Dalli的默认值近年来发生了变化 - 默认情况下,nil-caching的标志目前是假的。见https://github.com/petergoldstein/dalli

绝对值得添加测试来检查您的设置是否符合您的预期(特别是对于生产模式)