acts_as_cached 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README ADDED
@@ -0,0 +1,4 @@
1
+ ActsAsCached
2
+ ============
3
+
4
+ Description goes here
@@ -0,0 +1,77 @@
1
+ require 'active_record'
2
+ require 'view_extensions'
3
+
4
+ module Adocca
5
+ module Acts
6
+ module ActsAsCached
7
+
8
+ class CacheObserver
9
+
10
+ # class_name: The name of the class whose namespace we'll invalidate
11
+ # id_column: The column of the monitored object that contains the id
12
+ # of the object we'll invalidate
13
+ # type_column: For polymorphic associations, this is the column of the
14
+ # monitored object that contains the class name of the
15
+ # associated object. E.g. for trigs, "triggable_type"
16
+
17
+ def initialize(class_name, id_column, type_column = nil)
18
+ @class_name, @id_column, @type_column = class_name, id_column, type_column
19
+ end
20
+
21
+ def update(method_name, object)
22
+ if method_name == :after_save || method_name == :after_destroy
23
+ # in case of polymorphic associations, make sure the monitored object
24
+ # is attached to the right type
25
+ if @type_column.nil? || object[@type_column] == @class_name
26
+ namespace = "#{@class_name}:#{object[@id_column]}"
27
+ #puts 'Invalidating: ' + namespace + ' for change on object ' + object.class.name
28
+ RAILS_DEFAULT_LOGGER.debug "ActsAsCached, Invalidating namespace: #{namespace}"
29
+ CACHE.invalidate_namespace(namespace)
30
+ end
31
+ end
32
+ true
33
+ end
34
+ end
35
+
36
+ def self.append_features(base)
37
+ super
38
+ base.extend(ClassMethods)
39
+ end
40
+
41
+ module ClassMethods
42
+ def acts_as_cached(options = {})
43
+ if assocs = options[:depends]
44
+ assocs = [ assocs ] if assocs.kind_of? Symbol
45
+
46
+ assocs.each do |assoc|
47
+ unless reflection = reflect_on_association(assoc)
48
+ raise "Association not found"
49
+ end
50
+
51
+ # For trough reflections, we need to observe both the
52
+ # intermediate model (e.g. Tagging for tags) and the
53
+ # and the associated (Tag for tags)
54
+ # For now, only the through reflection since it's pain
55
+ # in the ASS to do this correctly. This works for tags :)
56
+ if through = reflection.through_reflection
57
+ reflection = through
58
+ end
59
+
60
+ if as = reflection.options[:as]
61
+ type_column = "#{as}_type"
62
+ else
63
+ type_column = nil
64
+ end
65
+
66
+ reflection.klass.add_observer CacheObserver.new(self.name, reflection.primary_key_name, type_column)
67
+ end
68
+ end
69
+
70
+ self.add_observer CacheObserver.new(self.name, self.primary_key.to_sym)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ ActiveRecord::Base.send(:include, Adocca::Acts::ActsAsCached)
@@ -0,0 +1,83 @@
1
+ require 'set'
2
+
3
+ ActionView::Base.class_eval do
4
+ class RenderOptions
5
+
6
+ def initialize(*init_values)
7
+ @set = Set.new(init_values)
8
+ end
9
+
10
+ def <<(key)
11
+ @set << key
12
+ end
13
+
14
+ def length
15
+ @set.length
16
+ end
17
+
18
+ alias_method :add, :<<
19
+
20
+ def method_missing(name)
21
+ if name.to_s =~ /(\w+)\?/
22
+ return @set.include?($1.to_sym)
23
+ else
24
+ super
25
+ end
26
+ end
27
+
28
+ def to_key
29
+ @set.to_a.collect{ |sym| sym.to_s }.sort.join(':')
30
+ end
31
+
32
+ end
33
+
34
+ def render_object(object, view, options = {})
35
+
36
+ logger.info "render_cached: object: #{object} view: #{view} options #{options.inspect}"
37
+
38
+
39
+ # XXX validate that object is an acts_as_cached FIXME
40
+
41
+ namespace = "#{object.class.name}:#{object.id}"
42
+ if render_options = options[:options]
43
+ key = "#{view}:#{render_options.to_key}"
44
+ else
45
+ render_options = RenderOptions.new
46
+ key = view
47
+ end
48
+
49
+ fragment_proc = Proc.new do
50
+ partial = options[:partial]
51
+ class_lower = object.class.name.underscore
52
+ unless partial
53
+ if directory = options[:directory]
54
+ partial = "#{directory}/#{class_lower}_#{view}"
55
+ else
56
+ partial = "#{class_lower}_#{view}"
57
+ end
58
+ end
59
+ render :partial => partial, :locals => { class_lower.to_sym => object, :options => render_options }
60
+ end
61
+
62
+ unless options[:cache] == false
63
+ fragment = cache_value([namespace, key], options[:expiry] || 0, &fragment_proc)
64
+ else
65
+ fragment = fragment_proc.call
66
+ end
67
+
68
+ if transformer = options[:transform]
69
+ case transformer
70
+ when Symbol
71
+ return send(transformer, object, fragment)
72
+ when Proc
73
+ return transformer.call(object, fragment)
74
+ else
75
+ raise TypeError, "Transformer must be either symbol or proc"
76
+ end
77
+ else
78
+ return fragment
79
+ end
80
+
81
+ end
82
+ end
83
+
@@ -0,0 +1,8 @@
1
+ require 'test/unit'
2
+
3
+ class ActsAsCachedTest < Test::Unit::TestCase
4
+ # Replace this with your real tests.
5
+ def test_this_plugin
6
+ flunk
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: acts_as_cached
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2006-11-13 00:00:00 +01:00
8
+ summary: Caching helpers for Rails
9
+ require_paths:
10
+ - lib
11
+ email:
12
+ homepage:
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: acts_as_cached
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Adocca Entertainment AB
31
+ files:
32
+ - lib/acts_as_cached.rb
33
+ - lib/view_extensions.rb
34
+ - test/acts_as_cached_test.rb
35
+ - README
36
+ test_files: []
37
+
38
+ rdoc_options:
39
+ - --line-numbers
40
+ - --inline-source
41
+ extra_rdoc_files:
42
+ - README
43
+ executables: []
44
+
45
+ extensions: []
46
+
47
+ requirements: []
48
+
49
+ dependencies: []
50
+