Module: ActiveModel::Serializer::Caching::ClassMethods

Defined in:
lib/active_model/serializer/concerns/caching.rb

Instance Method Summary collapse

Instance Method Details

#_attributes_keysObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

maps attribute value to explicit key name

See Also:

  • Serializer::attribute
  • Serializer::fragmented_attributes

75
76
77
78
79
80
81
# File 'lib/active_model/serializer/concerns/caching.rb', line 75

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_digestObject


48
49
50
51
# File 'lib/active_model/serializer/concerns/caching.rb', line 48

def _cache_digest
  return @_cache_digest if defined?(@_cache_digest)
  @_cache_digest = digest_caller_file(_cache_digest_file_path)
end

#_skip_digest?Boolean

Returns:

  • (Boolean)

67
68
69
# File 'lib/active_model/serializer/concerns/caching.rb', line 67

def _skip_digest?
  _cache_options && _cache_options[:skip_digest]
end

#cache(options = {}) ⇒ Object

TODO:

require less code comments. See

Enables a serializer to be automatically cached

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

when Rails.configuration.action_controller.perform_caching

github.com/rails-api/active_model_serializers/pull/1249#issuecomment-146567837

Examples:

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

  has_many :comments
end

Parameters:

  • options (Hash) (defaults to: {})

    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


117
118
119
120
121
122
123
124
125
126
# File 'lib/active_model/serializer/concerns/caching.rb', line 117

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?Boolean

Returns:

  • (Boolean)

162
163
164
# File 'lib/active_model/serializer/concerns/caching.rb', line 162

def cache_enabled?
  perform_caching? && cache_store && !_cache_only && !_cache_except
end

#cache_read_multi(collection_serializer, adapter_instance, include_directive) ⇒ Hash

Read cache from cache_store Used in CollectionSerializer to set :cached_attributes

Returns:

  • (Hash)

174
175
176
177
178
179
180
181
182
# File 'lib/active_model/serializer/concerns/caching.rb', line 174

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_storenil, ...

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

Returns:

  • (nil)

    when _cache is not set (i.e. when `cache` has not been called)

  • (._cache)

    when _cache is not the NullStore

  • (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`.

  • (nil)

    when _cache is the NullStore and ActiveModelSerializers.config.cache_store is nil.


152
153
154
155
156
157
158
159
160
# File 'lib/active_model/serializer/concerns/caching.rb', line 152

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) ⇒ Object

Hashes contents of file for _cache_digest


54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/active_model/serializer/concerns/caching.rb', line 54

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?Boolean

Returns:

  • (Boolean)

166
167
168
169
# File 'lib/active_model/serializer/concerns/caching.rb', line 166

def fragment_cache_enabled?
  perform_caching? && cache_store &&
    (_cache_only && !_cache_except || !_cache_only && _cache_except)
end

#fragmented_attributesObject


83
84
85
86
87
88
89
90
91
92
# File 'lib/active_model/serializer/concerns/caching.rb', line 83

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) ⇒ Object


42
43
44
45
46
# File 'lib/active_model/serializer/concerns/caching.rb', line 42

def inherited(base)
  caller_line = caller[1]
  base._cache_digest_file_path = caller_line
  super
end

#object_cache_key(serializer, adapter_instance) ⇒ String?

Returns the cache_key of the serializer or nil.

Returns:

  • (String, nil)

    the cache_key of the serializer or nil


212
213
214
215
216
# File 'lib/active_model/serializer/concerns/caching.rb', line 212

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) ⇒ Array

Find all cache_key for the collection_serializer

Parameters:

Returns:

  • (Array)

    all cache_key of collection_serializer


189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/active_model/serializer/concerns/caching.rb', line 189

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_cachingtrue, false Also known as: perform_caching?

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. Memoizes value of config first time it is called with a non-nil value. rubocop:disable Style/ClassVars

Returns:

  • (true, false)

135
136
137
138
# File 'lib/active_model/serializer/concerns/caching.rb', line 135

def perform_caching
  return @@perform_caching if defined?(@@perform_caching) && !@@perform_caching.nil?
  @@perform_caching = ActiveModelSerializers.config.perform_caching
end