public
Rubygem
Description: Rails Plugin - memoize and store to the db a record attribute generated by any expression or SQL query.
Homepage: http://6brand.com
Clone URL: git://github.com/JackDanger/cached_values.git
Search Repo:
finished most of the renaming

git-svn-id: http://svn.6brand.com/projects/plugins/cached_values@350 
7491b73d-821b-0410-9297-ad1f6b5b4194
studioda (author)
Fri Aug 31 08:14:52 -0700 2007
commit  d867d0fe9661dd5af9459899a35afc49d6e2d22b
tree    8433a1041a390945f3c4d7b600baa03336766381
parent  6ce2dda5e8e4ad2891951aba389c30ddfafd86fc
...
5
6
7
8
 
9
10
11
12
13
14
15
 
16
17
18
...
5
6
7
 
8
9
10
11
12
13
14
 
15
16
17
18
0
@@ -5,14 +5,14 @@
0
 desc 'Default: run unit tests.'
0
 task :default => :test
0
 
0
-desc 'Test the has_cached_value plugin.'
0
+desc 'Test the cached_values plugin.'
0
 Rake::TestTask.new(:test) do |t|
0
   t.libs << 'lib'
0
   t.pattern = 'test/**/*_test.rb'
0
   t.verbose = true
0
 end
0
 
0
-desc 'Generate documentation for the has_cached_value plugin.'
0
+desc 'Generate documentation for the cached_values plugin.'
0
 Rake::RDocTask.new(:rdoc) do |rdoc|
0
   rdoc.rdoc_dir = 'rdoc'
0
   rdoc.title = 'HasCachedValue'
...
1
 
2
...
 
1
2
0
@@ -1,3 +1,3 @@
0
-require 'has_cached_value'
0
+require 'cached_values'
0
 ActiveRecord::Base.send :include, HasCachedValueExtension
...
1
 
2
3
4
5
6
7
8
 
9
10
11
12
13
14
15
16
17
18
19
...
35
36
37
38
 
39
40
 
41
42
43
44
45
 
46
47
48
49
50
 
51
52
 
53
54
55
56
 
57
58
59
60
 
61
62
63
64
 
65
66
67
 
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
...
86
87
88
89
90
91
92
 
 
 
93
94
95
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
98
99
100
101
 
 
102
103
104
105
106
 
 
 
107
108
109
110
111
112
 
 
 
 
 
 
 
113
114
115
116
117
 
 
 
 
 
 
118
119
120
121
 
 
 
122
123
124
 
 
 
125
 
126
 
 
 
 
127
128
129
 
 
130
131
132
 
 
 
133
134
135
136
137
138
139
140
141
 
 
 
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
 
198
199
...
 
1
2
3
4
5
6
7
 
8
9
10
11
12
13
14
15
16
17
18
19
...
35
36
37
 
38
39
 
40
41
42
43
44
 
45
46
47
48
49
 
50
51
 
52
53
54
55
 
56
57
58
59
 
60
61
62
63
 
64
65
66
 
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
...
86
87
88
 
 
 
 
89
90
91
92
 
 
 
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
 
 
 
143
144
145
 
 
 
 
146
147
148
149
150
 
 
 
 
151
152
153
154
155
156
157
158
159
 
 
 
160
161
162
163
164
165
166
 
 
 
167
168
169
170
171
 
172
173
174
175
176
177
178
179
180
181
182
 
 
183
184
185
186
 
187
188
189
190
 
 
 
 
 
 
 
 
191
192
193
194
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
196
197
0
@@ -1,11 +1,11 @@
0
-module HasCachedValueExtension # :nodoc:
0
+module CachedValues # :nodoc:
0
   def self.included(base)
0
     base.extend(ClassMethods)
0
   end
0
   module ClassMethods
0
     # USAGE:
0
     #
0
- # a very simple case in which has_cached_value works just like the .count method on a has_many association:
0
+ # a very simple case in which cached_values works just like the .count method on a has_many association:
0
     #
0
     # class Company < ActiveRecord::Base
0
     # caches_value :total_employees, :sql => 'select count(*) from employees where company_id = #{id}'
0
0
0
0
0
0
0
0
0
@@ -35,36 +35,36 @@
0
     #
0
     
0
     def caches_value(association_id, options = {})
0
- reflection = create_has_cached_value_reflection(association_id, options)
0
+ reflection = create__cached_value_reflection(association_id, options)
0
 
0
- configure_dependency_for_has_cached_value(reflection)
0
+ configure_dependency_for__cached_value(reflection)
0
 
0
       reflection.options[:counter_cache] = reflection.options.delete(:cache) if reflection.options[:cache]
0
       reflection.options[:counter_cache] ||= reflection.name unless false == reflection.options[:counter_cache]
0
 
0
- association_accessor_method(reflection, ActiveRecord::Associations::HasCachedValueAssociation)
0
+ association_accessor_method(reflection, ActiveRecord::CachedValue)
0
     end
0
 
0
     private
0
     
0
- def configure_dependency_for_has_cached_value(reflection)
0
+ def configure_dependency_for__cached_value(reflection)
0
         if reflection.options[:counter_cache] && reflection.options[:cache]
0
- raise ArgumentError, ":cache is an alias for :counter_cache, don't use both options for has_cached_value in #{self.name}"
0
+ raise ArgumentError, ":cache is an alias for :counter_cache, don't use both options for caches_value in #{self.name}"
0
         end
0
       
0
         if !reflection.options[:sql] && !reflection.options[:eval]
0
- raise ArgumentError, "You must specify either the :eval or :sql options for has_cached_value in #{self.name}"
0
+ raise ArgumentError, "You must specify either the :eval or :sql options for caches_value in #{self.name}"
0
         end
0
       
0
         if reflection.options[:sql] && reflection.options[:eval]
0
- raise ArgumentError, ":eval and :sql are mutually exclusive options. You may specify one or the other for has_cached_value in #{self.name}"
0
+ raise ArgumentError, ":eval and :sql are mutually exclusive options. You may specify one or the other for caches_value in #{self.name}"
0
         end
0
       end
0
     
0
- def create_has_cached_value_reflection(association_id, options)
0
+ def create__cached_value_reflection(association_id, options)
0
         options.assert_valid_keys(:sql, :eval, :cache, :counter_cache)
0
         
0
- reflection = ActiveRecord::Reflection::AssociationReflection.new(:has_cached_value, association_id, options, self)
0
+ reflection = ActiveRecord::Reflection::MacroReflection.new(:cached_value, association_id, options, self)
0
         write_inheritable_hash :reflections, association_id => reflection
0
         reflection
0
       end
0
0
0
0
0
0
0
0
0
0
0
0
0
0
@@ -86,115 +86,113 @@
0
 end
0
 
0
 module ActiveRecord
0
- module Associations
0
- class HasCachedValueAssociation
0
- attr_reader :reflection
0
- instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$)/ }
0
+ class CachedValue
0
+ attr_reader :reflection
0
+ instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$)/ }
0
 
0
- def initialize(owner, reflection)
0
- @owner, @reflection = owner, reflection
0
- reset
0
+ def initialize(owner, reflection)
0
+ @owner, @reflection = owner, reflection
0
+ reset
0
+ end
0
+
0
+ def reset
0
+ @target = nil
0
+ @loaded = false
0
+ end
0
+
0
+ def load
0
+ reset
0
+ load_target
0
+ end
0
+
0
+ def reload
0
+ reset
0
+ clear_cache
0
+ load_target
0
+ end
0
+
0
+ def clear
0
+ clear_cache
0
+ @owner.instance_variable_set("@#{@reflection.name}", nil)
0
+ end
0
+
0
+ def loaded?
0
+ @loaded
0
+ end
0
+
0
+ def loaded
0
+ @loaded = true
0
+ end
0
+
0
+ def target
0
+ @target
0
+ end
0
+
0
+ protected
0
+
0
+ def find_target_by_eval
0
+ if @reflection.options[:eval].is_a?(String)
0
+ eval(@reflection.options[:eval], @owner.send(:binding))
0
+ elsif @reflection.options[:eval].is_a?(Proc)
0
+ @reflection.options[:eval].call(@owner)
0
+ else
0
+ raise ArgumentError.new("The :eval option on a cached_values must be either a String or a Proc")
0
+ end
0
       end
0
       
0
- def reset
0
- @target = nil
0
- @loaded = false
0
+ def find_target_by_sql
0
+ @owner.class.count_by_sql(sanitize_sql(interpolate_sql(@reflection.options[:sql])))
0
       end
0
-
0
- def load
0
- reset
0
- load_target
0
+
0
+ def find_target_from_cache
0
+ @owner.send(:read_attribute, @reflection.counter_cache_column) if has_cached_counter?
0
       end
0
 
0
- def reload
0
- reset
0
- clear_cache
0
- load_target
0
+ def find_target
0
+ target = find_target_from_cache
0
+ unless target
0
+ target ||= @reflection.options[:sql] ? find_target_by_sql : find_target_by_eval
0
+ update_cache(target)
0
+ end
0
+ target
0
       end
0
       
0
- def clear
0
- clear_cache
0
- @owner.instance_variable_set("@#{@reflection.name}", nil)
0
+ def update_cache(value)
0
+ return unless has_cached_counter?
0
+ unless @owner.new_record?
0
+ @owner.class.update_all(["#{@reflection.counter_cache_column} = ?", value], ["id = ?", @owner.id])
0
+ end
0
+ @owner.send(:write_attribute, @reflection.counter_cache_column, value)
0
       end
0
-
0
- def loaded?
0
- @loaded
0
+
0
+ def clear_cache
0
+ update_cache(nil)
0
       end
0
       
0
- def loaded
0
+ def load_target
0
+ return nil unless defined?(@loaded)
0
+ @target = find_target unless loaded?
0
         @loaded = true
0
+ @target
0
       end
0
+
0
+ def has_cached_counter?
0
+ @reflection.options[:counter_cache] && @owner.attribute_names.include?(@reflection.options[:counter_cache].to_s)
0
+ end
0
       
0
- def target
0
- @target
0
+ def interpolate_sql(sql, record = nil)
0
+ @owner.send(:interpolate_sql, sql, record)
0
       end
0
 
0
- protected
0
+ def sanitize_sql(sql)
0
+ @owner.class.send(:sanitize_sql, sql)
0
+ end
0
       
0
- def find_target_by_eval
0
- if @reflection.options[:eval].is_a?(String)
0
- eval(@reflection.options[:eval], @owner.send(:binding))
0
- elsif @reflection.options[:eval].is_a?(Proc)
0
- @reflection.options[:eval].call(@owner)
0
- else
0
- raise ArgumentError.new("The :eval option on a has_cached_value must be either a String or a Proc")
0
- end
0
+ def method_missing(method, *args, &block)
0
+ if load_target
0
+ @target.send(method, *args, &block)
0
         end
0
-
0
- def find_target_by_sql
0
- @owner.class.count_by_sql(sanitize_sql(interpolate_sql(@reflection.options[:sql])))
0
- end
0
-
0
- def find_target_from_cache
0
- @owner.send(:read_attribute, @reflection.counter_cache_column) if has_cached_counter?
0
- end
0
-
0
- def find_target
0
- target = find_target_from_cache
0
- unless target
0
- target ||= @reflection.options[:sql] ? find_target_by_sql : find_target_by_eval
0
- update_cache(target)
0
- end
0
- target
0
- end
0
-
0
- def update_cache(value)
0
- return unless has_cached_counter?
0
- unless @owner.new_record?
0
- @owner.class.update_all(["#{@reflection.counter_cache_column} = ?", value], ["id = ?", @owner.id])
0
- end
0
- @owner.send(:write_attribute, @reflection.counter_cache_column, value)
0
- end
0
-
0
- def clear_cache
0
- update_cache(nil)
0
- end
0
-
0
- def load_target
0
- return nil unless defined?(@loaded)
0
- @target = find_target unless loaded?
0
- @loaded = true
0
- @target
0
- end
0
-
0
- def has_cached_counter?
0
- @reflection.options[:counter_cache] && @owner.attribute_names.include?(@reflection.options[:counter_cache].to_s)
0
- end
0
-
0
- def interpolate_sql(sql, record = nil)
0
- @owner.send(:interpolate_sql, sql, record)
0
- end
0
-
0
- def sanitize_sql(sql)
0
- @owner.class.send(:sanitize_sql, sql)
0
- end
0
-
0
- def method_missing(method, *args, &block)
0
- if load_target
0
- @target.send(method, *args, &block)
0
- end
0
- end
0
- end
0
+ end
0
   end
0
 end
...
1
2
 
3
4
...
1
 
2
3
4
0
@@ -1,5 +1,5 @@
0
 # desc "Explaining what the task does"
0
-# task :has_cached_value do
0
+# task :cached_values do
0
 # # Task goes here
0
 # end

Comments

    No one has commented yet.