public
Description: simple identity map for active record. eager loading associations FTL
Clone URL: git://github.com/technoweenie/active_record_context.git
Click here to lend your support to: active_record_context and make a donation at www.pledgie.com !
add support for reload

git-svn-id: 
http://svn.techno-weenie.net/projects/plugins/active_record_context@2984 
567b1171-46fb-0310-a4c9-b4bef9110e78
technoweenie (author)
Sat Sep 29 11:21:22 -0700 2007
commit  53307381cc6ae0ce3a4783ea732570bfaa9fe3c8
tree    bf4fcd730c1d22abe9a69ab21c9b6a39fbf5a39a
parent  9fb24fc500d1e617626660449c34cefc58ff7155
...
1
2
 
3
...
 
1
2
3
0
@@ -1 +1 @@
0
-ActiveRecord::Base.send :extend, Technoweenie::ActiveRecordContext
0
\ No newline at end of file
0
+ActiveRecord::Base.send :include, Technoweenie::ActiveRecordContext
0
\ No newline at end of file
...
1
2
3
4
5
6
7
 
 
 
 
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
...
1
2
 
 
 
 
 
3
4
5
6
7
 
 
 
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
10
11
12
13
14
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
0
@@ -1,67 +1,77 @@
0
 module Technoweenie
0
   module ActiveRecordContext
0
- def self.extended(base)
0
- class << base
0
- alias_method_chain :find_every, :context
0
- alias_method_chain :find_one, :context
0
- end
0
+ def self.included(base)
0
+ base.extend ClassMethods
0
+ base.alias_method_chain :reload, :context
0
+ base.cattr_accessor :context_cache
0
     end
0
-
0
- mattr_accessor :log_context_activity
0
- mattr_reader :context_cache
0
 
0
- # Preloads the record from the given array of IDs. The ids should all be the same type.
0
- # You can pass an array of active record models if that model belongs to the current one.
0
- #
0
- # users = User.find :all
0
- # Avatar.prefetch users # performs this automatically: users.collect { |user| user.avatar_id }
0
- #
0
- def prefetch(ids)
0
- return [] if ids.blank?
0
- initial = ids.first
0
- ids = ids.collect { |record| record.send(prefetch_default) } if initial.respond_to?(prefetch_default)
0
- ids.compact!
0
- ids.uniq!
0
- find :all, :conditions => { :id => ids }
0
- end
0
-
0
- # defaults to the foreign key of the current model
0
- #
0
- # Avatar => avatar_id
0
- def prefetch_default
0
- @prefetch_default ||= name.foreign_key
0
- end
0
-
0
- def find_every_with_context(options)
0
- returning find_every_without_context(options) do |records|
0
- store_in_context records
0
+ module ClassMethods
0
+ def self.extended(base)
0
+ class << base
0
+ alias_method_chain :find_every, :context
0
+ alias_method_chain :find_one, :context
0
+ end
0
       end
0
- end
0
-
0
- def find_one_with_context(id, options)
0
- record = options[:conditions].nil? && cached[id.to_i]
0
- logger.debug("[Context] #{record ? :Found : :Missed} #{name} ##{id}") if log_context_activity
0
- record ? record : find_one_without_context(id, options)
0
- end
0
-
0
- def cached
0
- context_cache ? (context_cache[self.base_class] ||= {}) : {}
0
- end
0
-
0
- def store_in_context(records)
0
- return if context_cache.nil?
0
- logger.debug "[Context] Storing #{name} records: #{records.collect(&:id).to_sentence}" if log_context_activity
0
- records.inject(cached) do |memo, record|
0
- memo.update record.id => record
0
+
0
+ # Preloads the record from the given array of IDs. The ids should all be the same type.
0
+ # You can pass an array of active record models if that model belongs to the current one.
0
+ #
0
+ # users = User.find :all
0
+ # Avatar.prefetch users # performs this automatically: users.collect { |user| user.avatar_id }
0
+ #
0
+ def prefetch(ids)
0
+ return [] if ids.blank?
0
+ initial = ids.first
0
+ ids = ids.collect { |record| record.send(prefetch_default) } if initial.respond_to?(prefetch_default)
0
+ ids.compact!
0
+ ids.uniq!
0
+ find :all, :conditions => { :id => ids }
0
+ end
0
+
0
+ # defaults to the foreign key of the current model
0
+ #
0
+ # Avatar => avatar_id
0
+ def prefetch_default
0
+ @prefetch_default ||= name.foreign_key
0
+ end
0
+
0
+ def find_every_with_context(options)
0
+ returning find_every_without_context(options) do |records|
0
+ store_in_context records
0
+ end
0
+ end
0
+
0
+ def find_one_with_context(id, options)
0
+ record = options[:conditions].nil? && cached[id.to_i]
0
+ logger.debug("[Context] #{record ? :Found : :Missed} #{name} ##{id}")
0
+ record ? record : find_one_without_context(id, options)
0
+ end
0
+
0
+ def cached
0
+ context_cache ? (context_cache[self.base_class] ||= {}) : {}
0
+ end
0
+
0
+ def store_in_context(records)
0
+ return if context_cache.nil?
0
+ logger.debug "[Context] Storing #{name} records: #{records.collect(&:id).to_sentence}"
0
+ records.inject(cached) do |memo, record|
0
+ memo.update record.id => record
0
+ end
0
+ end
0
+
0
+ # Enables the context cache inside this block.
0
+ def with_context
0
+ self.context_cache = {}
0
+ yield
0
+ ensure
0
+ self.context_cache = nil
0
       end
0
     end
0
     
0
- # Enables the context cache inside this block.
0
- def with_context
0
- @@context_cache = {}
0
- yield
0
- ensure
0
- @@context_cache = nil
0
+ def reload_with_context(options = nil)
0
+ self.class.cached[id.to_i] = nil
0
+ reload_without_context(options)
0
     end
0
   end
0
 end
0
\ No newline at end of file
...
16
17
18
19
 
20
21
22
...
16
17
18
 
19
20
21
22
0
@@ -16,7 +16,7 @@ ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'sqlite'])
0
 
0
 load(File.dirname(__FILE__) + "/schema.rb")
0
 
0
-ActiveRecord::Base.send :extend, Technoweenie::ActiveRecordContext
0
+ActiveRecord::Base.send :include, Technoweenie::ActiveRecordContext
0
 
0
 class Topic < ActiveRecord::Base
0
 end
...
87
88
89
 
 
 
 
 
 
 
 
 
90
...
87
88
89
90
91
92
93
94
95
96
97
98
99
0
@@ -87,4 +87,13 @@ class ActiveRecordContextTest < Test::Unit::TestCase
0
     Topic.expects(:find).with(:all, :conditions => {:id => [@topic.id]})
0
     Topic.prefetch @posts
0
   end
0
+
0
+ def test_should_reload_record
0
+ Post.with_context do
0
+ @post = Post.find @posts.first.id
0
+ assert_equal 'normal body', @post.body
0
+ Post.update_all ['body = ?', 'foo bar']
0
+ assert_equal 'foo bar', @post.reload.body
0
+ end
0
+ end
0
 end

Comments

    No one has commented yet.