module ActiveModel::Serializer::Caching::ClassMethods
Public Instance Methods
@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
# 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
# File lib/active_model/serializer/concerns/caching.rb, line 69 def _skip_digest? _cache_options && _cache_options[:skip_digest] end
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
# File lib/active_model/serializer/concerns/caching.rb, line 164 def cache_enabled? perform_caching? && cache_store && !_cache_only && !_cache_except end
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
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
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
# 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
# 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
# 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
@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
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
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