Froze rails gems
[depot.git] / vendor / rails / actionpack / lib / action_controller / caching / sweeping.rb
1 module ActionController #:nodoc:
2 module Caching
3 # Sweepers are the terminators of the caching world and responsible for expiring caches when model objects change.
4 # They do this by being half-observers, half-filters and implementing callbacks for both roles. A Sweeper example:
5 #
6 # class ListSweeper < ActionController::Caching::Sweeper
7 # observe List, Item
8 #
9 # def after_save(record)
10 # list = record.is_a?(List) ? record : record.list
11 # expire_page(:controller => "lists", :action => %w( show public feed ), :id => list.id)
12 # expire_action(:controller => "lists", :action => "all")
13 # list.shares.each { |share| expire_page(:controller => "lists", :action => "show", :id => share.url_key) }
14 # end
15 # end
16 #
17 # The sweeper is assigned in the controllers that wish to have its job performed using the <tt>cache_sweeper</tt> class method:
18 #
19 # class ListsController < ApplicationController
20 # caches_action :index, :show, :public, :feed
21 # cache_sweeper :list_sweeper, :only => [ :edit, :destroy, :share ]
22 # end
23 #
24 # In the example above, four actions are cached and three actions are responsible for expiring those caches.
25 #
26 # You can also name an explicit class in the declaration of a sweeper, which is needed if the sweeper is in a module:
27 #
28 # class ListsController < ApplicationController
29 # caches_action :index, :show, :public, :feed
30 # cache_sweeper OpenBar::Sweeper, :only => [ :edit, :destroy, :share ]
31 # end
32 module Sweeping
33 def self.included(base) #:nodoc:
34 base.extend(ClassMethods)
35 end
36
37 module ClassMethods #:nodoc:
38 def cache_sweeper(*sweepers)
39 configuration = sweepers.extract_options!
40
41 sweepers.each do |sweeper|
42 ActiveRecord::Base.observers << sweeper if defined?(ActiveRecord) and defined?(ActiveRecord::Base)
43 sweeper_instance = (sweeper.is_a?(Symbol) ? Object.const_get(sweeper.to_s.classify) : sweeper).instance
44
45 if sweeper_instance.is_a?(Sweeper)
46 around_filter(sweeper_instance, :only => configuration[:only])
47 else
48 after_filter(sweeper_instance, :only => configuration[:only])
49 end
50 end
51 end
52 end
53 end
54
55 if defined?(ActiveRecord) and defined?(ActiveRecord::Observer)
56 class Sweeper < ActiveRecord::Observer #:nodoc:
57 attr_accessor :controller
58
59 def before(controller)
60 self.controller = controller
61 callback(:before) if controller.perform_caching
62 end
63
64 def after(controller)
65 callback(:after) if controller.perform_caching
66 # Clean up, so that the controller can be collected after this request
67 self.controller = nil
68 end
69
70 protected
71 # gets the action cache path for the given options.
72 def action_path_for(options)
73 ActionController::Caching::Actions::ActionCachePath.path_for(controller, options)
74 end
75
76 # Retrieve instance variables set in the controller.
77 def assigns(key)
78 controller.instance_variable_get("@#{key}")
79 end
80
81 private
82 def callback(timing)
83 controller_callback_method_name = "#{timing}_#{controller.controller_name.underscore}"
84 action_callback_method_name = "#{controller_callback_method_name}_#{controller.action_name}"
85
86 __send__(controller_callback_method_name) if respond_to?(controller_callback_method_name, true)
87 __send__(action_callback_method_name) if respond_to?(action_callback_method_name, true)
88 end
89
90 def method_missing(method, *arguments)
91 return if @controller.nil?
92 @controller.__send__(method, *arguments)
93 end
94 end
95 end
96 end
97 end