【问题标题】:How does Rails generate the view cache key?Rails 如何生成视图缓存键?
【发布时间】:2026-01-03 05:20:04
【问题描述】:

我一直想知道 Rails 是如何生成缓存的,尤其是:

cache [@users, @products]

表现得像:

cache @users.concat(@products)

【问题讨论】:

    标签: ruby-on-rails caching activesupport


    【解决方案1】:

    方法是:

      # Expands out the +key+ argument into a key that can be used for the
      # cache store. Optionally accepts a namespace, and all keys will be
      # scoped within that namespace.
      #
      # If the +key+ argument provided is an array, or responds to +to_a+, then
      # each of elements in the array will be turned into parameters/keys and
      # concatenated into a single key. For example:
      #
      #   expand_cache_key([:foo, :bar])               # => "foo/bar"
      #   expand_cache_key([:foo, :bar], "namespace")  # => "namespace/foo/bar"
      #
      # The +key+ argument can also respond to +cache_key+ or +to_param+.
      def expand_cache_key(key, namespace = nil)
        expanded_cache_key = namespace ? "#{namespace}/" : ""
    
        if prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
          expanded_cache_key << "#{prefix}/"
        end
    
        expanded_cache_key << retrieve_cache_key(key)
        expanded_cache_key
      end
    

    让我们定义一个快捷方式:

    def cache(*args); ActiveSupport::Cache.expand_cache_key(*args); end
    

    为了可读性:

    ENV["RAILS_CACHE_ID"] = ''
    

    所以它是递归的,例如:

    cache 'string'
    => "/string"
    
    cache [1, 2]
    => "/1/2"
    
    cache [1, 2, 3, 4]
    => "/1/2/3/4"
    
    cache [1, 2], [3, 4]
    => "[3, 4]//1/2"
    
    cache [[1, 2], [3, 4]]
    => "/1/2/3/4"
    
    cache [@users, @products]
    => "/users/207311-20140409135446308087000/users/207312-20140401185427926822000/products/1-20130531221550045078000/products/2-20131109180059828964000/products/1-20130531221550045078000/products/2-20131109180059828964000"
    
    cache @users.concat(@products)
    => "/users/207311-20140409135446308087000/users/207312-20140401185427926822000/products/1-20130531221550045078000/products/2-20131109180059828964000/products/1-20130531221550045078000/products/2-20131109180059828964000"
    

    如您所见,第二个参数是命名空间,因此始终将参数放在数组中

    所以回答我的问题,是一样的。

    【讨论】: