module ActiveModel::Serializer::Caching::ClassMethods

Public Instance Methods

_attributes_keys() click to toggle source

@api private maps attribute value to explicit key name @see Serializer::attribute @see Serializer::fragmented_attributes

# File lib/active_model/serializer/concerns/caching.rb, line 77
def _attributes_keys
  _attributes_data
    .each_with_object({}) do |(key, attr), hash|
    next if key == attr.name
    hash[attr.name] = { key: key }
  end
end
_cache_digest() click to toggle source
# File lib/active_model/serializer/concerns/caching.rb, line 50
def _cache_digest
  return @_cache_digest if defined?(@_cache_digest)
  @_cache_digest = digest_caller_file(_cache_digest_file_path)
end
_skip_digest?() click to toggle source
# File lib/active_model/serializer/concerns/caching.rb, line 69
def _skip_digest?
  _cache_options && _cache_options[:skip_digest]
end
cache(options = {}) click to toggle source

Enables a serializer to be automatically cached

Sets ::_cache object to ActionController::Base.cache_store

when Rails.configuration.action_controller.perform_caching

@param options [Hash] with valid keys:

cache_store    : @see ::_cache
key            : @see ::_cache_key
only           : @see ::_cache_only
except         : @see ::_cache_except
skip_digest    : does not include digest in cache_key
all else       : @see ::_cache_options

@example

class PostSerializer < ActiveModel::Serializer
  cache key: 'post', expires_in: 3.hours
  attributes :title, :body

  has_many :comments
end

@todo require less code comments. See github.com/rails-api/active_model_serializers/pull/1249#issuecomment-146567837

# File lib/active_model/serializer/concerns/caching.rb, line 119
def cache(options = {})
  self._cache =
    options.delete(:cache_store) ||
    ActiveModelSerializers.config.cache_store ||
    ActiveSupport::Cache.lookup_store(:null_store)
  self._cache_key = options.delete(:key)
  self._cache_only = options.delete(:only)
  self._cache_except = options.delete(:except)
  self._cache_options = options.empty? ? nil : options
end
cache_enabled?() click to toggle source
# File lib/active_model/serializer/concerns/caching.rb, line 164
def cache_enabled?
  perform_caching? && cache_store && !_cache_only && !_cache_except
end
cache_read_multi(collection_serializer, adapter_instance, include_directive) click to toggle source

Read cache from cache_store @return [Hash] Used in CollectionSerializer to set :cached_attributes

# File lib/active_model/serializer/concerns/caching.rb, line 176
def cache_read_multi(collection_serializer, adapter_instance, include_directive)
  return {} if ActiveModelSerializers.config.cache_store.blank?

  keys = object_cache_keys(collection_serializer, adapter_instance, include_directive)

  return {} if keys.blank?

  ActiveModelSerializers.config.cache_store.read_multi(*keys)
end
cache_store() click to toggle source

The canonical method for getting the cache store for the serializer.

@return [nil] when _cache is not set (i.e. when `cache` has not been called) @return [._cache] when _cache is not the NullStore @return [ActiveModelSerializers.config.cache_store] when _cache is the NullStore.

This is so we can use `cache` being called to mean the serializer should be cached
even if ActiveModelSerializers.config.cache_store has not yet been set.
That means that when _cache is the NullStore and ActiveModelSerializers.config.cache_store
is configured, `cache_store` becomes `ActiveModelSerializers.config.cache_store`.

@return [nil] when _cache is the NullStore and ActiveModelSerializers.config.cache_store is nil.

# File lib/active_model/serializer/concerns/caching.rb, line 154
def cache_store
  return nil if _cache.nil?
  return _cache if _cache.class != ActiveSupport::Cache::NullStore
  if ActiveModelSerializers.config.cache_store
    self._cache = ActiveModelSerializers.config.cache_store
  else
    nil
  end
end
digest_caller_file(caller_line) click to toggle source

Hashes contents of file for _cache_digest

# File lib/active_model/serializer/concerns/caching.rb, line 56
        def digest_caller_file(caller_line)
          serializer_file_path = caller_line[CALLER_FILE]
          serializer_file_contents = IO.read(serializer_file_path)
          Digest::MD5.hexdigest(serializer_file_contents)
        rescue TypeError, Errno::ENOENT
          warn <<-EOF.strip_heredoc
            Cannot digest non-existent file: '#{caller_line}'.
            Please set `::_cache_digest` of the serializer
            if you'd like to cache it.
            EOF
          ''.freeze
        end
fragment_cache_enabled?() click to toggle source
# File lib/active_model/serializer/concerns/caching.rb, line 168
def fragment_cache_enabled?
  perform_caching? && cache_store &&
    (_cache_only && !_cache_except || !_cache_only && _cache_except)
end
fragmented_attributes() click to toggle source
# File lib/active_model/serializer/concerns/caching.rb, line 85
def fragmented_attributes
  cached = _cache_only ? _cache_only : _attributes - _cache_except
  cached = cached.map! { |field| _attributes_keys.fetch(field, field) }
  non_cached = _attributes - cached
  non_cached = non_cached.map! { |field| _attributes_keys.fetch(field, field) }
  {
    cached: cached,
    non_cached: non_cached
  }
end
inherited(base) click to toggle source
Calls superclass method
# File lib/active_model/serializer/concerns/caching.rb, line 44
def inherited(base)
  caller_line = caller[1]
  base._cache_digest_file_path = caller_line
  super
end
object_cache_key(serializer, adapter_instance) click to toggle source

@return [String, nil] the cache_key of the serializer or nil

# File lib/active_model/serializer/concerns/caching.rb, line 214
def object_cache_key(serializer, adapter_instance)
  return unless serializer.present? && serializer.object.present?

  (serializer.class.cache_enabled? || serializer.class.fragment_cache_enabled?) ? serializer.cache_key(adapter_instance) : nil
end
object_cache_keys(collection_serializer, adapter_instance, include_directive) click to toggle source

Find all cache_key for the collection_serializer @param serializers [ActiveModel::Serializer::CollectionSerializer] @param adapter_instance [ActiveModelSerializers::Adapter::Base] @param include_directive [JSONAPI::IncludeDirective] @return [Array] all cache_key of collection_serializer

# File lib/active_model/serializer/concerns/caching.rb, line 191
def object_cache_keys(collection_serializer, adapter_instance, include_directive)
  cache_keys = []

  collection_serializer.each do |serializer|
    cache_keys << object_cache_key(serializer, adapter_instance)

    serializer.associations(include_directive).each do |association|
      # TODO(BF): Process relationship without evaluating lazy_association
      association_serializer = association.lazy_association.serializer
      if association_serializer.respond_to?(:each)
        association_serializer.each do |sub_serializer|
          cache_keys << object_cache_key(sub_serializer, adapter_instance)
        end
      else
        cache_keys << object_cache_key(association_serializer, adapter_instance)
      end
    end
  end

  cache_keys.compact.uniq
end
perform_caching() click to toggle source

Value is from ActiveModelSerializers.config.perform_caching. Is used to globally enable or disable all serializer caching, just like Rails.configuration.action_controller.perform_caching, which is its default value in a Rails application. @return [true, false] Memoizes value of config first time it is called with a non-nil value. rubocop:disable Style/ClassVars

# File lib/active_model/serializer/concerns/caching.rb, line 137
def perform_caching
  return @@perform_caching if defined?(@@perform_caching) && !@@perform_caching.nil?
  @@perform_caching = ActiveModelSerializers.config.perform_caching
end
Also aliased as: perform_caching?
perform_caching?()
Alias for: perform_caching