Module: RocketPants::Caching

Extended by:
ActiveSupport::Concern
Defined in:
lib/rocket_pants/controller/caching.rb

Overview

RocketPants::Caching adds unobtrusive support for automatic HTTP-level caching to controllers built on Rocket Pants. It will automatically.

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.cache_key_for(object) ⇒ Object

Returns the default cache key for a given object. Note that when the object defines a rp_object_key method, it will be used as the

Parameters:

  • the (Object, #rp_object_key)

    object to find the cache key for.



65
66
67
68
69
70
71
72
# File 'lib/rocket_pants/controller/caching.rb', line 65

def cache_key_for(object)
  if object.respond_to?(:rp_object_key) && (ok = object.rp_object_key).present?
    Digest::MD5.hexdigest ok
  else
    suffix = (object.respond_to?(:new?) && object.new?) ? "new" : object.id
    Digest::MD5.hexdigest "#{object.class.name}/#{suffix}"
  end
end

.etag_for(object) ⇒ Object

Given an object, returns the etag value to be used in the response / etag header (prior to any more processing). If the object isn’t in the cache, we’ll instead record it and return the etag for it.

Parameters:

  • object (#cache_key)

    what to look up the etag for



54
55
56
57
58
# File 'lib/rocket_pants/controller/caching.rb', line 54

def etag_for(object)
  cache_key = cache_key_for(object)
  etag_value = RocketPants.cache[cache_key].presence || record(object, cache_key)
  "#{cache_key}:#{etag_value}"
end

.normalise_etag(identifier_or_object) ⇒ Object



74
75
76
# File 'lib/rocket_pants/controller/caching.rb', line 74

def normalise_etag(identifier_or_object)
  %("#{identifier_or_object.to_s}")
end

.record(object, cache_key = cache_key_for(object)) ⇒ Object

Takes a given object and sets the stored etag in the Rocket Pants etag key to have the correct value.

Doing this means that on subsequent requests with caching enabled, the request will be automatically recorded by the middleware and not actually served.

Please note that this expects the object has a cache_key method defined that will return a string, useable for caching. If not, it will use inspect which is a VERY VERY bad idea (and will likely be removed in the near future).

Parameters:

  • object (#cache_key)

    what to record in the cache



40
41
42
43
44
45
46
47
# File 'lib/rocket_pants/controller/caching.rb', line 40

def record(object, cache_key = cache_key_for(object))
  default_etag = object.inspect
  if object.respond_to?(:cache_key).presence && (ck = object.cache_key).present?
    default_etag = ck
  end
  generated_etag = Digest::MD5.hexdigest(default_etag)
  RocketPants.cache[cache_key] = generated_etag
end

.remove(object) ⇒ Object

Removes the cache record for a given object, making sure It isn’t contained in the Rocket Pants etag cache thus ignoring it in incoming responses.

Parameters:

  • object (Object)

    what to remove from the cache



23
24
25
# File 'lib/rocket_pants/controller/caching.rb', line 23

def remove(object)
  RocketPants.cache.delete cache_key_for(object)
end

Instance Method Details

#cache_action?(action = ) ⇒ Boolean

Returns:

  • (Boolean)


107
108
109
# File 'lib/rocket_pants/controller/caching.rb', line 107

def cache_action?(action = params[:action])
  RocketPants.caching_enabled? && cached_actions.include?(action)
end

#cache_response(resource, single_resource) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/rocket_pants/controller/caching.rb', line 111

def cache_response(resource, single_resource)
  # Add in the default options.
  response.cache_control.merge! caching_options
  # We need to set the etag based on the object when it is singular
  # Note that the object is responsible for clearing the etag cache.
  if single_resource
    response["ETag"] = Caching.normalise_etag Caching.etag_for(resource)
  # Otherwise, it's a collection and we need to use time based caching.
  else
    response.cache_control[:max_age] = caching_timeout
  end
end

#post_process_exposed_object(resource, type, singular) ⇒ Object

The callback use to automatically cache the current response object, using it’s cache key as a guide. For collections, instead of using an etag we’ll use the request path as a cache key and instead use a timeout.



127
128
129
130
131
132
# File 'lib/rocket_pants/controller/caching.rb', line 127

def post_process_exposed_object(resource, type, singular)
  super # Make sure we invoke the old hook.
  if cache_action?
    cache_response resource, singular
  end
end