acts_as_cached 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +4 -0
- data/lib/acts_as_cached.rb +77 -0
- data/lib/view_extensions.rb +83 -0
- data/test/acts_as_cached_test.rb +8 -0
- metadata +50 -0
data/README
ADDED
@@ -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
|
+
|
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
|
+
|