mirror of https://github.com/rails/rails
Move caching/fragments in ActionMailer and ActionController to action_dispatch/caching/fragments
This commit is contained in:
parent
049b6e670f
commit
a24d067343
|
@ -1,14 +1,11 @@
|
|||
require 'active_support/descendants_tracker'
|
||||
require 'action_dispatch/caching/fragments'
|
||||
|
||||
module ActionMailer
|
||||
module Caching
|
||||
extend ActiveSupport::Concern
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
eager_autoload do
|
||||
autoload :Fragments
|
||||
end
|
||||
|
||||
module ConfigMethods
|
||||
def cache_store
|
||||
config.cache_store
|
||||
|
@ -26,7 +23,7 @@ module ActionMailer
|
|||
|
||||
include AbstractController::Helpers
|
||||
include ConfigMethods
|
||||
include Fragments
|
||||
include ActionDispatch::Caching::Fragments
|
||||
|
||||
included do
|
||||
extend ConfigMethods
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
require 'action_dispatch/caching/fragments'
|
||||
require 'fileutils'
|
||||
require 'uri'
|
||||
|
||||
|
@ -26,10 +27,6 @@ module ActionController
|
|||
extend ActiveSupport::Concern
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
eager_autoload do
|
||||
autoload :Fragments
|
||||
end
|
||||
|
||||
module ConfigMethods
|
||||
def cache_store
|
||||
config.cache_store
|
||||
|
@ -48,7 +45,7 @@ module ActionController
|
|||
include AbstractController::Callbacks
|
||||
|
||||
include ConfigMethods
|
||||
include Fragments
|
||||
include ActionDispatch::Caching::Fragments
|
||||
|
||||
included do
|
||||
extend ConfigMethods
|
||||
|
|
|
@ -1,148 +0,0 @@
|
|||
module ActionController
|
||||
module Caching
|
||||
# Fragment caching is used for caching various blocks within
|
||||
# views without caching the entire action as a whole. This is
|
||||
# useful when certain elements of an action change frequently or
|
||||
# depend on complicated state while other parts rarely change or
|
||||
# can be shared amongst multiple parties. The caching is done using
|
||||
# the +cache+ helper available in the Action View. See
|
||||
# ActionView::Helpers::CacheHelper for more information.
|
||||
#
|
||||
# While it's strongly recommended that you use key-based cache
|
||||
# expiration (see links in CacheHelper for more information),
|
||||
# it is also possible to manually expire caches. For example:
|
||||
#
|
||||
# expire_fragment('name_of_cache')
|
||||
module Fragments
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
if respond_to?(:class_attribute)
|
||||
class_attribute :fragment_cache_keys
|
||||
else
|
||||
mattr_writer :fragment_cache_keys
|
||||
end
|
||||
|
||||
self.fragment_cache_keys = []
|
||||
|
||||
helper_method :fragment_cache_key if respond_to?(:helper_method)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# Allows you to specify controller-wide key prefixes for
|
||||
# cache fragments. Pass either a constant +value+, or a block
|
||||
# which computes a value each time a cache key is generated.
|
||||
#
|
||||
# For example, you may want to prefix all fragment cache keys
|
||||
# with a global version identifier, so you can easily
|
||||
# invalidate all caches.
|
||||
#
|
||||
# class ApplicationController
|
||||
# fragment_cache_key "v1"
|
||||
# end
|
||||
#
|
||||
# When it's time to invalidate all fragments, simply change
|
||||
# the string constant. Or, progressively roll out the cache
|
||||
# invalidation using a computed value:
|
||||
#
|
||||
# class ApplicationController
|
||||
# fragment_cache_key do
|
||||
# @account.id.odd? ? "v1" : "v2"
|
||||
# end
|
||||
# end
|
||||
def fragment_cache_key(value = nil, &key)
|
||||
self.fragment_cache_keys += [key || ->{ value }]
|
||||
end
|
||||
end
|
||||
|
||||
# Given a key (as described in +expire_fragment+), returns
|
||||
# a key suitable for use in reading, writing, or expiring a
|
||||
# cached fragment. All keys begin with <tt>views/</tt>,
|
||||
# followed by any controller-wide key prefix values, ending
|
||||
# with the specified +key+ value. The key is expanded using
|
||||
# ActiveSupport::Cache.expand_cache_key.
|
||||
def fragment_cache_key(key)
|
||||
head = self.class.fragment_cache_keys.map { |k| instance_exec(&k) }
|
||||
tail = key.is_a?(Hash) ? url_for(key).split("://").last : key
|
||||
ActiveSupport::Cache.expand_cache_key([*head, *tail], :views)
|
||||
end
|
||||
|
||||
# Writes +content+ to the location signified by
|
||||
# +key+ (see +expire_fragment+ for acceptable formats).
|
||||
def write_fragment(key, content, options = nil)
|
||||
return content unless cache_configured?
|
||||
|
||||
key = fragment_cache_key(key)
|
||||
instrument_fragment_cache :write_fragment, key do
|
||||
content = content.to_str
|
||||
cache_store.write(key, content, options)
|
||||
end
|
||||
content
|
||||
end
|
||||
|
||||
# Reads a cached fragment from the location signified by +key+
|
||||
# (see +expire_fragment+ for acceptable formats).
|
||||
def read_fragment(key, options = nil)
|
||||
return unless cache_configured?
|
||||
|
||||
key = fragment_cache_key(key)
|
||||
instrument_fragment_cache :read_fragment, key do
|
||||
result = cache_store.read(key, options)
|
||||
result.respond_to?(:html_safe) ? result.html_safe : result
|
||||
end
|
||||
end
|
||||
|
||||
# Check if a cached fragment from the location signified by
|
||||
# +key+ exists (see +expire_fragment+ for acceptable formats).
|
||||
def fragment_exist?(key, options = nil)
|
||||
return unless cache_configured?
|
||||
key = fragment_cache_key(key)
|
||||
|
||||
instrument_fragment_cache :exist_fragment?, key do
|
||||
cache_store.exist?(key, options)
|
||||
end
|
||||
end
|
||||
|
||||
# Removes fragments from the cache.
|
||||
#
|
||||
# +key+ can take one of three forms:
|
||||
#
|
||||
# * String - This would normally take the form of a path, like
|
||||
# <tt>pages/45/notes</tt>.
|
||||
# * Hash - Treated as an implicit call to +url_for+, like
|
||||
# <tt>{ controller: 'pages', action: 'notes', id: 45}</tt>
|
||||
# * Regexp - Will remove any fragment that matches, so
|
||||
# <tt>%r{pages/\d*/notes}</tt> might remove all notes. Make sure you
|
||||
# don't use anchors in the regex (<tt>^</tt> or <tt>$</tt>) because
|
||||
# the actual filename matched looks like
|
||||
# <tt>./cache/filename/path.cache</tt>. Note: Regexp expiration is
|
||||
# only supported on caches that can iterate over all keys (unlike
|
||||
# memcached).
|
||||
#
|
||||
# +options+ is passed through to the cache store's +delete+
|
||||
# method (or <tt>delete_matched</tt>, for Regexp keys).
|
||||
def expire_fragment(key, options = nil)
|
||||
return unless cache_configured?
|
||||
key = fragment_cache_key(key) unless key.is_a?(Regexp)
|
||||
|
||||
instrument_fragment_cache :expire_fragment, key do
|
||||
if key.is_a?(Regexp)
|
||||
cache_store.delete_matched(key, options)
|
||||
else
|
||||
cache_store.delete(key, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def instrument_fragment_cache(name, key) # :nodoc:
|
||||
payload = {
|
||||
controller: controller_name,
|
||||
action: action_name,
|
||||
key: key
|
||||
}
|
||||
|
||||
ActiveSupport::Notifications.instrument("#{name}.action_controller", payload) { yield }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
module ActionMailer
|
||||
module ActionDispatch
|
||||
module Caching
|
||||
# Fragment caching is used for caching various blocks within
|
||||
# views without caching the entire action as a whole. This is
|
Loading…
Reference in New Issue